কীভাবে অ্যানড্রয়েড পরিষেবা ক্রিয়াকলাপের সাথে যোগাযোগ করবে


251

আমি আমার প্রথম অ্যান্ড্রয়েড অ্যাপ্লিকেশন লিখছি এবং পরিষেবা এবং ক্রিয়াকলাপের মধ্যে যোগাযোগের বিষয়ে আমার মাথা পেতে চেষ্টা করছি। আমার একটি পরিষেবা রয়েছে যা পটভূমিতে চলবে এবং কিছু জিপিএস এবং সময় ভিত্তিক লগিং করবে। আমার একটি ক্রিয়াকলাপ থাকবে যা পরিষেবা শুরু এবং বন্ধ করতে ব্যবহৃত হবে।

সুতরাং প্রথমে, কার্যকলাপটি শুরু হওয়ার পরে পরিষেবাটি চলছে কিনা তা আমার জানতে সক্ষম হওয়া দরকার। সে সম্পর্কে এখানে আরও কিছু প্রশ্ন রয়েছে, তাই আমি মনে করি আমি এটি নির্ধারণ করতে পারি (তবে পরামর্শ দেওয়ার জন্য নির্দ্বিধায়)।

আমার আসল সমস্যা: যদি ক্রিয়াকলাপটি চলমান থাকে এবং পরিষেবা শুরু হয়, তবে পরিষেবাটির ক্রিয়াকলাপে বার্তা প্রেরণের জন্য আমার একটি উপায় প্রয়োজন। এই মুহুর্তে সরল স্ট্রিংস এবং পূর্ণসংখ্যা - বেশিরভাগ স্থিতি বার্তা। বার্তাগুলি নিয়মিত হবে না, তাই আমি মনে করি না যদি অন্য কোনও উপায় থাকে তবে পরিষেবাটি পোলিং করা ভাল উপায়। আমি কেবল এই যোগাযোগটি চাই যখন ব্যবহারকারী দ্বারা কার্যকলাপ শুরু করা হয় - আমি পরিষেবা থেকে ক্রিয়াকলাপ শুরু করতে চাই না। অন্য কথায়, আপনি যদি ক্রিয়াকলাপ শুরু করেন এবং পরিষেবাটি চলমান থাকে, আকর্ষণীয় কিছু ঘটলে আপনি কার্যকলাপ UI তে কিছু স্থিতি বার্তা দেখতে পাবেন। আপনি যদি কার্যকলাপ শুরু না করেন, আপনি এই বার্তাগুলি দেখতে পাবেন না (সেগুলি এত আকর্ষণীয় নয়)।

দেখে মনে হচ্ছে পরিষেবাটি চালু আছে কিনা তা আমার নির্ধারণের পক্ষে সক্ষম হওয়া উচিত এবং যদি তাই হয় তবে শ্রোতা হিসাবে ক্রিয়াকলাপ যুক্ত করুন। তারপরে ক্রিয়াকলাপটি বিরতি দেয় বা থামলে শ্রোতা হিসাবে ক্রিয়াকলাপটি সরান। আসলেই কি তা সম্ভব? এটি করার একমাত্র উপায় হ'ল ক্রিয়াকলাপটি পার্সলেবল প্রয়োগ করা এবং একটি এইডআইএল ফাইল তৈরি করা যাতে আমি এটিকে পরিষেবাটির দূরবর্তী ইন্টারফেসের মধ্য দিয়ে যেতে পারি। এটি যদিও ওভারকিলের মতো বলে মনে হচ্ছে এবং কীভাবে ক্রিয়াকলাপটি রাইটটো পার্সেল () / রিডফ্রোম পার্সেল () প্রয়োগ করতে হবে তা আমার কোনও ধারণা নেই।

এর চেয়ে সহজ বা আরও ভাল কোন উপায় আছে? কোন সাহায্যের জন্য ধন্যবাদ।

সম্পাদনা করুন:

পরবর্তী সময়ে যে কেউ এই বিষয়ে আগ্রহী তাদের জন্য, স্যাম্পল ডিরেক্টরিতে এটিআইডিএলের মাধ্যমে এটি পরিচালনা করার জন্য গুগলের কাছ থেকে নমুনা কোড রয়েছে: /apis/app/RemoteService.java

উত্তর:


94

পরিষেবাগুলির সাথে যোগাযোগের জন্য তিনটি সুস্পষ্ট উপায় রয়েছে:

  1. ইন্টেন্টস ব্যবহার করে
  2. এইআইডিএল ব্যবহার করছি
  3. পরিষেবা অবজেক্টটি নিজেই ব্যবহার করে (একক হিসাবে)

আপনার ক্ষেত্রে, আমি বিকল্পটি 3 নিয়ে যাব it এটি পরিষেবাটি নিজেই একটি স্ট্যাটিক রেফারেন্স তৈরি করুন এবং এটি অনক্রিট () এ সেট করুন:

void onCreate(Intent i) {
  sInstance = this;
}

একটি স্ট্যাটিক ফাংশন তৈরি করুন MyService getInstance(), যা স্ট্যাটিককে ফিরিয়ে দেয় sInstance

তারপরে Activity.onCreate()আপনি পরিষেবাটি শুরু করার সময়, পরিষেবাটি শুরু না হওয়া পর্যন্ত অবিচ্ছিন্নভাবে অপেক্ষা করুন (ক্রিয়াকলাপের উদ্দেশ্যে একটি উদ্দেশ্য প্রেরণ করে আপনার পরিষেবাটি এটি প্রস্তুত আপনার অ্যাপটিকে অবহিত করতে পারে)) এবং এর উদাহরণটি পান। উদাহরণস্বরূপ, আপনার পরিষেবা শ্রোতাদের আপত্তি আপনার পরিষেবাতে নিবন্ধভুক্ত করুন এবং আপনি সেট হয়ে গেছেন। দ্রষ্টব্য: ক্রিয়াকলাপের ভিতরে ভিউগুলি সম্পাদনা করার সময় আপনার সেগুলি ইউআই থ্রেডে সংশোধন করা উচিত, পরিষেবাটি সম্ভবত নিজস্ব থ্রেডটি চালাবে, সুতরাং আপনাকে কল করার দরকার আছেActivity.runOnUiThread()

আপনার শেষ কাজটি হ'ল আপনার শ্রোতার মধ্যে থাকা রেফারেন্সটি সরিয়ে ফেলা Activity.onPause() , অন্যথায় আপনার ক্রিয়াকলাপের প্রসঙ্গে একটি উদাহরণ ফুটে উঠবে, ভাল নয়।

দ্রষ্টব্য: এই পদ্ধতিটি কেবল তখনই কার্যকর যখন আপনার অ্যাপ্লিকেশন / ক্রিয়াকলাপ / কার্যটি একমাত্র প্রক্রিয়া যা আপনার পরিষেবা অ্যাক্সেস করবে। যদি এটি না হয় তবে আপনাকে বিকল্প 1 বা 2 ব্যবহার করতে হবে।


2
আমি কীভাবে busy-waitকার্যকলাপ করতে পারি ? আপনি দয়া করে ব্যাখ্যা করতে পারেন?
আইটুরকি

1
সুতরাং হয় আপনার পরিষেবা ক্লাসে অনক্রিটের পরে বা স্টার্টকম্যান্ডের পরে একটি সর্বজনীন স্ট্যাটিক ভেরিয়েবল সেট করুন, একে সংযুক্ত বা সত্যকে কিছু বলুন। তারপরে আপনার ক্রিয়াকলাপে এটি করুন: ইনটেন্ট ইন্টেন্ট = নতুন ইনটেন্ট (অ্যাক্ট, ইয়োর সার্ভিস.ক্লাস); startService (অভিপ্রায়); যখন (! আপনারসেবা.আইস কানেক্টেড) {ঘুম (300); Op এর লুপের পরে আপনার পরিষেবাটি চালু আছে এবং আপনি এটির সাথে যোগাযোগ করতে পারেন .. আমার অভিজ্ঞতায় অবশ্যই এই জাতীয় পরিষেবার সাথে ইন্টারঅ্যাক্ট করার কিছু সীমাবদ্ধতা রয়েছে।
ম্যাট ওল্ফ

কেন এটি শুরু করা যেতে পারে Activity.onCreate()?
স্কাইওয়াল

তাদের মধ্যে বার্তাগুলির Intentsমাধ্যমে ডেটা প্রেরণ করে আপনি কেন ব্যবহার করতে চান না সে সম্পর্কে কোনও শব্দ Parcellable?
আমান আলম

2
এটি কাজ করে, তবে @ ম্যাক্সিমিউমগোটের উত্তরটি অনেক পরিষ্কার এবং কোনও ব্যস্ত-অপেক্ষায় জড়িত না।
ম্যাট

262

প্রশ্নকর্তা সম্ভবত এটি পেরিয়ে যাওয়ার অনেক আগে থেকেই চলে এসেছেন তবে অন্য কেউ যদি এটি অনুসন্ধান করে ...

এটি পরিচালনা করার আরও একটি উপায় আছে যা আমি মনে করি এটি সবচেয়ে সহজ।

BroadcastReceiverআপনার ক্রিয়াকলাপে একটি যুক্ত করুন । নিবন্ধন তাতে কিছু কাস্টম অভিপ্রায় গ্রহণ করতে onResumeএবং এটা নিবন্ধন মুক্ত onPause। তারপরে আপনি যখন নিজের স্ট্যাটাস আপডেটগুলি বা আপনার কাছে কী পাঠাতে চান তখন আপনার পরিষেবা থেকে সেই অভিপ্রায়টি প্রেরণ করুন।

নিশ্চিত হয়ে নিন যে অন্য কোনও অ্যাপ যদি আপনার Intent(কেউ কি কোনও দূষিত কিছু করতে পারে?) শোনেন তবে আপনি অসন্তুষ্ট হবেন না , তবে এর বাইরেও আপনার ঠিক আছে।

কোড নমুনা অনুরোধ করা হয়েছিল:

আমার পরিষেবাতে, আমার এটি রয়েছে:

// Do stuff that alters the content of my local SQLite Database
sendBroadcast(new Intent(RefreshTask.REFRESH_DATA_INTENT));

( RefreshTask.REFRESH_DATA_INTENTকেবলমাত্র একটি ধ্রুব স্ট্রিং))

আমার শ্রবণ ক্রিয়াকলাপে, আমি আমার সংজ্ঞা দিই BroadcastReceiver:

private class DataUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(RefreshTask.REFRESH_DATA_INTENT)) {
          // Do stuff - maybe update my view based on the changed DB contents
        }
    }
}

আমি ক্লাসের শীর্ষে আমার রিসিভারটি ঘোষণা করি:

private DataUpdateReceiver dataUpdateReceiver;

আমি onResumeএটি যুক্ত করতে ওভাররাইড :

if (dataUpdateReceiver == null) dataUpdateReceiver = new DataUpdateReceiver();
IntentFilter intentFilter = new IntentFilter(RefreshTask.REFRESH_DATA_INTENT);
registerReceiver(dataUpdateReceiver, intentFilter);

এবং আমি যুক্ত করতে ওভাররাইড onPause:

if (dataUpdateReceiver != null) unregisterReceiver(dataUpdateReceiver);

"আরে, নিজেকে আপডেট করুন" বলার জন্য এখন আমার ক্রিয়াকলাপ আমার পরিষেবা শুনছে listening আমি Intentডাটাবেস টেবিলগুলি আপডেট করার পরিবর্তে ডেটা পাস করতে পারতাম এবং তারপরে আমার ক্রিয়াকলাপের মধ্যে থাকা পরিবর্তনগুলি সন্ধান করতে আবার ফিরে যেতে পারতাম, তবে যেহেতু আমি পরিবর্তনগুলি যেভাবেই চালিয়ে যেতে চাই, তাই ডিবি-র মাধ্যমে ডেটা পাস করা বোধগম্য।


5
কিভাবে? আপনি যা বর্ণনা করেন তা হ'ল আমার প্রয়োজন। তবে এর চেয়েও বেশি, আমার সম্পূর্ণ স্যাম্পল কোড দরকার। আগাম ধন্যবাদ. এফওয়াইআই, শেষ বার যখন আমি একটি উইজেট লেখার চেষ্টা করেছি, বার্তার অংশটি আমাকে 2 মাস সময় নিয়েছিল। আপনি চাইলে হাসেন, তবে আইএমএইচও অ্যান্ড্রয়েড আইওএসের চেয়ে জটিল হওয়ায় আপনার বিশেষজ্ঞদের আরও প্রকাশ করা দরকার!

1
অ্যাএএএএএএ, অ্যাডভান্সড অ্যান্ড্রয়েড বিকাশের ব্যস্ত কোডারের গাইড উইজেটগুলির জন্য একটি দুর্দান্ত অধ্যায় রয়েছে। এই একমাত্র সংস্থান যা আমাকে সেই জগাখিচুড়ি দিয়েই পেয়েছে। কমন্সওয়্যার, লেখক, স্ট্যাকওভারফ্লোতে 115k খ্যাতি পেয়েছেন, এবং আমি বইটি অত্যন্ত সুপারিশ করি। commonsware.com/AdvAndroid
ম্যাক্সিমিয়ামগোট

64
Broadcastsচমত্কার এবং অতিরিক্ত হিসাবে আপনি যদি নিজের সম্প্রচারটি নিজের প্রক্রিয়া ছাড়িয়ে যেতে না চান তবে একটি ব্যবহার করে বিবেচনা করুন LocalBroadcast: developer.android.com/references/android/support/v4/content/…
কোডি কফলান

2
থ্যাঙ্কস কোডি, আমি এর আগে দেখিনি।
ম্যাক্সিমিয়ামগোট

3
এটি যোগাযোগের খুব ভাল উপায়। তবে যখন ফলাফল বিতরণকৃত অবস্থায় থাকত, তখন ফলাফলগুলি সরবরাহ করার ক্ষেত্রে কী করবেন? সুতরাং অনারিউম ক্রিয়াকলাপের পরে ফলাফলের জন্য দীর্ঘ সময় অপেক্ষা করতে পারে। এবং কোনও ডেটা প্রাপ্ত হবে না, কারণ ডেটা মিস হয়েছিল।
আন্তন-এম

39

ব্যবহার LocalBroadcastManagerআপনার অ্যাপ্লিকেশনটির অভ্যন্তরে স্থানীয় পরিষেবা থেকে প্রেরিত সম্প্রচারের জন্য শোনার জন্য কোনও প্রাপককে নিবন্ধিত করতে করুন, রেফারেন্সটি এখানে যায়:

http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html


3
হ্যাঁ, স্থানীয় সম্প্রচার সম্পর্কে একটি খুব সুন্দর আলোচনা এখানে লিঙ্কটি
সোহেলআজিজ

1
LocalBroadcastManagerএখন LiveDataবা অন্যান্য পর্যবেক্ষক প্যাটার্ন সরঞ্জামগুলির পক্ষে
হ্রাস করা হয়েছে

20

আমি অবাক হয়েছি যে কেউ অটো ইভেন্ট বাস লাইব্রেরির জন্য রেফারেন্স দেয় নি

http://square.github.io/otto/

আমি এটি আমার অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিতে ব্যবহার করছি এবং এটি নির্বিঘ্নে কাজ করে।


7
বিকল্পভাবে, গ্রীনরোবটের ইভেন্টবাস লাইব্রেরি রয়েছে।
জাজার

15
তবে মনে রাখবেন ইভেন্ট ইভেন্ট এবং অটো সর্বদা এক প্রক্রিয়াতে থাকে। যখন আপনি এমন কোনও পরিষেবা ব্যবহার করছেন যা তার নিজস্ব প্রক্রিয়াতে রয়েছে ( android:process=":my_service"তারা সেট করতে শুরু করে তারা যোগাযোগ করতে সক্ষম হয় না
রন

20

কোনও পরিষেবা এবং ক্রিয়াকলাপের মধ্যে যোগাযোগের জন্য ম্যাসেঞ্জার ব্যবহার করা অন্য একটি সহজ উপায়।

ক্রিয়াকলাপে, সংশ্লিষ্ট ম্যাসেঞ্জার সহ একটি হ্যান্ডলার তৈরি করুন। এটি আপনার পরিষেবা থেকে বার্তাগুলি পরিচালনা করবে।

class ResponseHandler extends Handler {
    @Override public void handleMessage(Message message) {
            Toast.makeText(this, "message from service",
                    Toast.LENGTH_SHORT).show();
    }
}
Messenger messenger = new Messenger(new ResponseHandler());

মেসেঞ্জারে কোনও বার্তায় এটি সংযুক্ত করে পরিষেবাটিতে পৌঁছে দেওয়া যেতে পারে:

Message message = Message.obtain(null, MyService.ADD_RESPONSE_HANDLER);
message.replyTo = messenger;
try {
    myService.send(message);
catch (RemoteException e) {
    e.printStackTrace();
}

একটি পূর্ণ উদাহরণ এপিআই ডেমোতে পাওয়া যাবে: ম্যাসেঞ্জার সার্ভিস এবং ম্যাসেঞ্জার সার্ভিসঅ্যাক্টিভিটি । মাই সার্ভিস কীভাবে কাজ করে তার পুরো উদাহরণটি দেখুন।


1
অনেক প্রশংসিত! পুরোপুরি কাজ করে। কোডটিতে কেবল একটি বিশদ: পরিবর্তে myService.send(message);হওয়া উচিত messenger.send(message);
ফেডেরিকো ক্রিস্টিনা

9

অন্যান্য মন্তব্যে উল্লিখিত না হওয়া অন্যান্য পদ্ধতিটি হ'ল বিন্ড সার্ভিস () ব্যবহার করে ক্রিয়াকলাপ থেকে পরিষেবার সাথে আবদ্ধ হওয়া এবং সার্ভিস কানেকশন কলব্যাকটিতে পরিষেবার একটি উদাহরণ পাওয়া। হিসাবে এখানে বর্ণিত http://developer.android.com/guide/components/bound-services.html


4
এটি পরিষেবা উদাহরণের রেফারেন্স পাওয়ার সঠিক উপায়।
13

9

আপনি এটি ব্যবহার করতে পারেন LiveDataযা একটির মতো কাজ করে EventBus

class MyService : LifecycleService() {
    companion object {
        var BUS = MutableLiveData<Object>()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val testItem : Object

        // expose your data
        if (BUS.hasActiveObservers()) {
            BUS.postValue(testItem)
        }

        return START_NOT_STICKY
    }
}

তারপরে আপনার একটি পর্যবেক্ষক যুক্ত করুন Activity

MyService.BUS.observe(this, Observer {
    it?.let {
        // Do what you need to do here
    }
})

আপনি এই ব্লগ থেকে আরও পড়তে পারেন


2

আর একটি উপায় হ'ল এমভিসি প্যাটার্নের প্রকরণটির ক্রিয়াকলাপ এবং সেবার মাধ্যমেই জাল মডেল শ্রেণীর সাথে পর্যবেক্ষকদের ব্যবহার করা যেতে পারে। এটি সম্পাদন করার সর্বোত্তম উপায় কিনা তা আমি জানি না, তবে এটি আমার পক্ষে কাজ করেছিল। আপনার যদি কিছু উদাহরণের প্রয়োজন হয় তবে এটি জিজ্ঞাসা করুন এবং আমি কিছু পোস্ট করব।


আমি একই চিন্তা সঙ্গে সংগ্রাম করছি। আমার ক্রিয়াকলাপ এবং 2 পরিষেবা রয়েছে যা একই মডেল have মডেলটি কোনও ক্রিয়াকলাপ বা যে কোনও সেবার ক্ষেত্রে আপডেট করা যেতে পারে তাই আমি পর্যবেক্ষকদের একরকম ব্যবহার করার কথা ভেবেছিলাম তবে তা বুঝতে পারছি না। আপনি আপনার ধারণা প্রদর্শন করতে উদাহরণ পোস্ট করতে পারেন?
pzo

2

আমার পদ্ধতি:

/ থেকে পরিষেবা / ক্রিয়াকলাপ থেকে বার্তা প্রেরণ এবং গ্রহণ পরিচালনা করতে শ্রেণি:

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MessageManager {

    public interface IOnHandleMessage{
        // Messages
        int MSG_HANDSHAKE = 0x1;

        void onHandleMessage(Message msg);
    }

    private static final String LOGCAT = MessageManager.class.getSimpleName();

    private Messenger mMsgSender;
    private Messenger mMsgReceiver;
    private List<Message> mMessages;

    public MessageManager(IOnHandleMessage callback, IBinder target){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_ACTIVITY));
        mMsgSender = new Messenger(target);
        mMessages = new ArrayList<>();
    }

    public MessageManager(IOnHandleMessage callback){
        mMsgReceiver = new Messenger(new MessageHandler(callback, MessageHandler.TYPE_SERVICE));
        mMsgSender = null;
        mMessages = new ArrayList<>();
    }

    /* START Getter & Setter Methods */
    public Messenger getMsgSender() {
        return mMsgSender;
    }

    public void setMsgSender(Messenger sender) {
        this.mMsgSender = sender;
    }

    public Messenger getMsgReceiver() {
        return mMsgReceiver;
    }

    public void setMsgReceiver(Messenger receiver) {
        this.mMsgReceiver = receiver;
    }

    public List<Message> getLastMessages() {
        return mMessages;
    }

    public void addMessage(Message message) {
        this.mMessages.add(message);
    }
    /* END Getter & Setter Methods */

    /* START Public Methods */
    public void sendMessage(int what, int arg1, int arg2, Bundle msgData){
        if(mMsgSender != null && mMsgReceiver != null) {
            try {
                Message msg = Message.obtain(null, what, arg1, arg2);
                msg.replyTo = mMsgReceiver;
                if(msgData != null){
                    msg.setData(msgData);
                }
                mMsgSender.send(msg);
            } catch (RemoteException rE) {
                onException(rE);
            }
        }
    }

    public void sendHandshake(){
        if(mMsgSender != null && mMsgReceiver != null){
            sendMessage(IOnHandleMessage.MSG_HANDSHAKE, 0, 0, null);
        }
    }
    /* END Public Methods */

    /* START Private Methods */
    private void onException(Exception e){
        Log.e(LOGCAT, e.getMessage());
        e.printStackTrace();
    }
    /* END Private Methods */

    /** START Private Classes **/
    private class MessageHandler extends Handler {

        // Types
        final static int TYPE_SERVICE = 0x1;
        final static int TYPE_ACTIVITY = 0x2;

        private IOnHandleMessage mCallback;
        private int mType;

        public MessageHandler(IOnHandleMessage callback, int type){
            mCallback = callback;
            mType = type;
        }

        @Override
        public void handleMessage(Message msg){
            addMessage(msg);
            switch(msg.what){
                case IOnHandleMessage.MSG_HANDSHAKE:
                    switch(mType){
                        case TYPE_SERVICE:
                            setMsgSender(msg.replyTo);
                            sendHandshake();
                            break;
                        case TYPE_ACTIVITY:
                            Log.v(LOGCAT, "HERE");
                            break;
                    }
                    break;
                default:
                    if(mCallback != null){
                        mCallback.onHandleMessage(msg);
                    }
                    break;
            }
        }

    }
    /** END Private Classes **/

}

ক্রিয়াকলাপের উদাহরণে:

public class activity extends AppCompatActivity
      implements     ServiceConnection,
                     MessageManager.IOnHandleMessage { 

    [....]

    private MessageManager mMessenger;

    private void initMyMessenger(IBinder iBinder){
        mMessenger = new MessageManager(this, iBinder);
        mMessenger.sendHandshake();
    }

    private void bindToService(){
        Intent intent = new Intent(this, TagScanService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        /* START THE SERVICE IF NEEDED */
    }

    private void unbindToService(){
    /* UNBIND when you want (onDestroy, after operation...)
        if(mBound) {
            unbindService(mServiceConnection);
            mBound = false;
        }
    }

    /* START Override MessageManager.IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
        switch(msg.what){
            case Constants.MSG_SYNC_PROGRESS:
                Bundle data = msg.getData();
                String text = data.getString(Constants.KEY_MSG_TEXT);
                setMessageProgress(text);
                break;
            case Constants.MSG_START_SYNC:
                onStartSync();
                break;
            case Constants.MSG_END_SYNC:
                onEndSync(msg.arg1 == Constants.ARG1_SUCCESS);
                mBound = false;
                break;
        }
    }
    /* END Override MessageManager.IOnHandleMessage Methods */

    /** START Override ServiceConnection Methods **/
    private class BLEScanServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            initMyMessenger(iBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mMessenger = null;
            mBound = false;
        }
    }
    /** END Override ServiceConnection Methods **/

পরিষেবার উদাহরণে:

public class Blablabla extends Service
    implements     MessageManager.IOnHandleMessage {

    [...]

    private MessageManager mMessenger;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        initMessageManager();
        return mMessenger.getMsgReceiver().getBinder();
    }

    private void initMessageManager(){
        mMessenger = new MessageManager(this);
    }

    /* START Override IOnHandleMessage Methods */
    @Override
    public void onHandleMessage(Message msg) {
    /* Do what you want when u get a message looking the "what" attribute */
    }
    /* END Override IOnHandleMessage Methods */

কার্যকলাপ / পরিষেবা থেকে একটি বার্তা পাঠান:

mMessenger.sendMessage(what, arg1, arg2, dataBundle);

এটি কীভাবে কাজ করে:

আপনি যে ক্রিয়াকলাপটি শুরু করেন বা পরিষেবা বাঁধেন সেই ক্রিয়াকলাপে পরিষেবা "অনবাইন্ড" পদ্ধতিগুলি তার মেসেজ ম্যানেজারকে বাইন্ডারটি ফিরিয়ে দেয়, "পরিষেবা সংযোগ" ইন্টারফেস পদ্ধতি প্রয়োগের মাধ্যমে "ক্রিয়াকলাপের মধ্যে" "অন সার্ভিস সংযুক্ত" আপনি এই আইবিন্ডারটি পেয়ে থাকেন এবং এটি ব্যবহার করে আপনাকে মেসেজম্যানেজারের উদ্যোগ দেয়। ক্রিয়াকলাপটি তার মেসেজ ম্যানেজারটি মেসেজহ্যান্ডলার প্রেরণ করার পরে পরিষেবাটিতে হ্যান্ডশেক প্রেরণ করে যাতে এটি তার "মেসেজহ্যান্ডলার" প্রেরককে ("ব্যক্তিগত বার্তাব্যাপী এমএমএসজিএসেন্ডার;" মেসেজ ম্যানেজারে) সেট করতে পারে। পরিষেবাটি করাটি তার বার্তা কে প্রেরণ করে তা জানেন।

আপনি মেসেজ ম্যানেজারে "প্রেরক" এর মেসেঞ্জারের একটি তালিকা / সারি ব্যবহার করে এটি বাস্তবায়ন করতে পারেন যাতে আপনি বিভিন্ন ক্রিয়াকলাপ / পরিষেবাদিতে একাধিক বার্তা প্রেরণ করতে পারেন বা আপনি বার্তা ম্যানেজারে "রিসিভার" মেসেঞ্জারের একটি তালিকা / সারিতে ব্যবহার করতে পারেন যাতে আপনি একাধিক গ্রহণ করতে পারেন বিভিন্ন ক্রিয়াকলাপ / পরিষেবা থেকে প্রাপ্ত বার্তা message

"মেসেজ ম্যানেজার" ইভেন্টে আপনার কাছে প্রাপ্ত সমস্ত বার্তার একটি তালিকা রয়েছে।

আপনি যেমন "ক্রিয়াকলাপের মেসেঞ্জার" এবং "সার্ভিস মেসেঞ্জার" এর মধ্যে এই "মেসেজ ম্যানেজার" উদাহরণটি ব্যবহার করে সেটি স্বয়ংক্রিয়ভাবে দেখতে পাচ্ছেন, এটি "অন সার্ভিস সংযুক্ত" পদ্ধতি এবং "হ্যান্ডশেক" ব্যবহারের মাধ্যমে করা হয়।

আশা করি এটি আপনার জন্য সহায়ক :) আপনাকে অনেক ধন্যবাদ! বাই: ডি


2

একটি কোড উদাহরণ সহ @ মিঃস্নোফ্লেক উত্তরটি অনুসরণ করতে। এটি এখন XABBER ওপেন সোর্স Applicationবর্গApplicationবর্গ centralizing এবং সমন্বয়ের হয় Listenersএবং ManagerInterfaces এবং আরো। সকল প্রকারের পরিচালকগণ গতিশীলভাবে লোড হয়। Activity´sজ্যাবারে শুরু হওয়া Listenerতারা কী ধরণের তা রিপোর্ট করবে । এবং যখন একটি Serviceশুরু এটি Applicationক্লাসে শুরু হিসাবে রিপোর্ট । এখন Activityআপনাকে যা করতে হবে তার সমস্ত বার্তাই প্রেরণ করা আপনার কী ধরণের প্রয়োজন তা আপনার Activityহয়ে উঠতে listenerহবে। ইন OnStart() OnPause()রেজিস্টার / unreg। Serviceঅনুরোধ করতে পারেন Applicationঠিক যে জন্য ক্লাসlistener এটা কথা বলতে চান এবং এটি যদি সেখানে তারপর এর কার্যকলাপ গ্রহণ করার জন্য প্রস্তুত।

মধ্য দিয়ে যাচ্ছে Applicationবর্গ দেখা হবে একটি লুণ্ঠন আরো তারপর এই ঘটছে আছে।


প্রদত্ত লিঙ্কটি এখন একটি গিথুব 404-এ ফলাফল করে it
JE কার্টার II

হ্যাঁ, এখন কাজ করছে বলে মনে হচ্ছে। গিথুব উপর অবশ্যই একটি অস্থায়ী সমস্যা ছিল।
জে জে কার্টার II

1

বাইন্ডিং যোগাযোগের অন্য উপায়

একটি কলব্যাক তৈরি করুন

public interface MyCallBack{

   public void getResult(String result);

}

ক্রিয়াকলাপের দিক:

  1. ক্রিয়াকলাপে ইন্টারফেস প্রয়োগ করুন

  2. পদ্ধতির জন্য বাস্তবায়ন সরবরাহ করুন

  3. ক্রিয়াকলাপের সাথে আবদ্ধ করুন

  4. ক্রিয়াকলাপের সাথে পরিষেবাটি আবদ্ধ ও আনবাউন্ড না হলে কলব্যাকটি নিবন্ধন করুন এবং নিবন্ধভুক্ত করুন।

    public class YourActivity extends AppCompatActivity implements MyCallBack{
    
          private Intent notifyMeIntent;
          private GPSService gpsService;
          private boolean bound = false;
    
          @Override
          public void onCreate(Bundle sis){
    
              // activity code ...
    
              startGPSService();
    
          }
    
          @Override
          public void getResult(String result){
           // show in textView textView.setText(result);
          }
    
          @Override
          protected void onStart()
          {
              super.onStart();
              bindService();
          }
    
          @Override
          protected void onStop() {
              super.onStop();
              unbindService();
          }
    
          private ServiceConnection serviceConnection = new ServiceConnection() {
    
                @Override
                public void onServiceConnected(ComponentName className, IBinder service) {
    
                      GPSService.GPSBinder binder = (GPSService.GPSBinder) service;
                      gpsService= binder.getService();
                      bound = true;
                      gpsService.registerCallBack(YourActivity.this); // register
    
               }
    
               @Override
               public void onServiceDisconnected(ComponentName arg0) {
                      bound = false;
               }
          };
    
          private void bindService() {
    
               bindService(notifyMeIntent, serviceConnection, Context.BIND_AUTO_CREATE);
          }
    
          private void unbindService(){
               if (bound) {
                     gpsService.registerCallBack(null); // unregister            
                     unbindService(serviceConnection);
                     bound = false;
                }
          }
    
          // Call this method somewhere to start Your GPSService
          private void startGPSService(){
               notifyMeIntent = new Intent(this, GPSService.class);
               startService(myIntent );
          }
    
     }

পরিষেবা দিক:

  1. কলব্যাক শুরু করুন

  2. যখনই প্রয়োজন হবে কলব্যাক পদ্ধতিটি চালু করুন

     public class GPSService extends Service{
    
         private MyCallBack myCallback;
         private IBinder serviceBinder = new GPSBinder();
    
         public void registerCallBack(MyCallBack myCallback){
              this.myCallback= myCallback;
         }
    
         public class GPSBinder extends Binder{
    
             public GPSService getService(){
                  return GPSService.this;
             }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent){
             return serviceBinder;
        }
     }

আপনার serviceConnectionবাইরে আছে onCreate। এটি সম্পাদনা করুন।
আদিল জাফর

এটি অনক্রিটের ভিতরে থাকতে হবে না
রোহিত সিং

0

মধুর উল্লেখ করেছেন, আপনি যোগাযোগের জন্য একটি বাস ব্যবহার করতে পারেন।

বাস ব্যবহারের ক্ষেত্রে আপনার কাছে কিছু বিকল্প রয়েছে:

অটো ইভেন্ট বাসের লাইব্রেরি (আরএক্সজাবার পক্ষে অবমূল্যায়ন)

http://square.github.io/otto/

গ্রিন রোবটের ইভেন্টবাস

http://greenrobot.org/eventbus/

এনওয়াইবাস (আরএক্সবাস, আরএক্সজেভা ব্যবহার করে প্রয়োগ করা হয়েছে। ইভেন্টবাসের সাথে খুব মিল)

https://github.com/MindorksOpenSource/NYBus


0

লোকালড্রোডকাস্টম্যানেজার ছাড়াও , ইভেন্ট বাস এবং ম্যাসেঞ্জার ইতিমধ্যে এই প্রশ্নের উত্তর দিয়েছে, আমরা পরিষেবা থেকে যোগাযোগ করার জন্য মুলতুবি ইন্টেন্ট ব্যবহার করতে পারি ।

আমার ব্লগ পোস্টে এখানে উল্লিখিত হিসাবে

পরিষেবাদি এবং ক্রিয়াকলাপের মধ্যে যোগাযোগ পেন্ডিং ইন্টেন্ট ব্যবহার করে করা যেতে পারে that এজন্য আমরা createPendResult () .CreatePendResult () ব্যবহার করতে পারি একটি নতুন পেন্ডিংসেন্টটেন্ট অবজেক্ট তৈরি করে যা আপনি পরিষেবাতে হস্তান্তর করতে পারেনঅ্যাক্টিভিটি রেজাল্টের অভ্যন্তরে আপনার ক্রিয়াকলাপে ফলাফল ডেটা প্রেরণ করতে (ইনট, ইন্টি, ইন্টেন্ট) কলব্যাক Sএখন একটি মুলতুবি ইন্ডেন্টটি পার্সেবল, এবং সুতরাং কোনও ইনটেন্ট অতিরিক্ত হিসাবে স্থাপন করা যেতে পারে, আপনার ক্রিয়াকলাপটি এই পেন্ডিং ইন্টেন্টটি পরিষেবাতে পাস করতে পারে service পরিষেবাটি পরিবর্তে, প্রেরণ () পদ্ধতিতে কলটি ইনডেন্টকে কল করতে পারে কোনও ইভেন্টের ক্রিয়াকলাপের ফলাফলের মাধ্যমে ক্রিয়াকলাপ।

কার্যকলাপ

public class PendingIntentActivity extends AppCompatActivity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PendingIntent pendingResult = createPendingResult(
100, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), PendingIntentService.class);
intent.putExtra("pendingIntent", pendingResult);
startService(intent);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100 && resultCode==200) {
Toast.makeText(this,data.getStringExtra("name"),Toast.LENGTH_LONG).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
}

সেবা

public class PendingIntentService extends Service {

    private static final String[] items= { "lorem", "ipsum", "dolor",
            "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi",
            "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam",
            "vel", "erat", "placerat", "ante", "porttitor", "sodales",
            "pellentesque", "augue", "purus" };
    private PendingIntent data;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        data = intent.getParcelableExtra("pendingIntent");

        new LoadWordsThread().start();
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    class LoadWordsThread extends Thread {
        @Override
        public void run() {
            for (String item : items) {
                if (!isInterrupted()) {

                    Intent result = new Intent();
                    result.putExtra("name", item);
                    try {
                        data.send(PendingIntentService.this,200,result);
                    } catch (PendingIntent.CanceledException e) {

                        e.printStackTrace();
                    }
                    SystemClock.sleep(400);

                }
            }
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.