android - गतिविधि के साथ एंड्रॉइड सेवा कैसे संवाद करें




android-activity android-service (7)

मैं अपना पहला एंड्रॉइड एप्लिकेशन लिख रहा हूं और सेवाओं और गतिविधियों के बीच संचार के आसपास अपना सिर लेने की कोशिश कर रहा हूं। मेरे पास एक ऐसी सेवा है जो पृष्ठभूमि में चलेगी और कुछ जीपीएस और समय आधारित लॉगिंग करेगी। मेरे पास एक गतिविधि होगी जिसका उपयोग सेवा शुरू करने और रोकने के लिए किया जाएगा।

तो सबसे पहले, मुझे यह पता लगाने में सक्षम होना चाहिए कि गतिविधि शुरू होने पर सेवा चल रही है या नहीं। इसके बारे में यहां कुछ अन्य प्रश्न हैं, इसलिए मुझे लगता है कि मैं इसे समझ सकता हूं (लेकिन सलाह देने के लिए स्वतंत्र महसूस करें)।

मेरी असली समस्या: यदि गतिविधि चल रही है और सेवा शुरू हो गई है, तो मुझे गतिविधि के लिए संदेश भेजने के लिए सेवा की आवश्यकता है। इस बिंदु पर सरल स्ट्रिंग्स और पूर्णांक - अधिकतर स्थिति संदेश। संदेश नियमित रूप से नहीं होंगे, इसलिए मुझे नहीं लगता कि अगर सेवा एक और तरीका है तो सेवा मतदान करना एक अच्छा तरीका है। जब उपयोगकर्ता द्वारा गतिविधि शुरू की जाती है तो मैं केवल यह संचार चाहता हूं - मैं सेवा से गतिविधि शुरू नहीं करना चाहता हूं। दूसरे शब्दों में, यदि आप गतिविधि शुरू करते हैं और सेवा चल रही है, तो कुछ दिलचस्प होने पर आपको गतिविधि UI में कुछ स्थिति संदेश दिखाई देंगे। यदि आप गतिविधि शुरू नहीं करते हैं, तो आप इन संदेशों को नहीं देख पाएंगे (वे उस रोचक नहीं हैं)।

ऐसा लगता है कि मुझे यह निर्धारित करने में सक्षम होना चाहिए कि सेवा चल रही है या नहीं, और यदि ऐसा है, तो गतिविधि को श्रोता के रूप में जोड़ें। फिर गतिविधि को रोकें या बंद होने पर गतिविधि को श्रोता के रूप में हटा दें। क्या यह वास्तव में संभव है? ऐसा करने का एकमात्र तरीका यह है कि गतिविधि को पार्ससेलबल लागू करना और एआईडीएल फ़ाइल बनाना है ताकि मैं इसे सेवा के दूरस्थ इंटरफ़ेस के माध्यम से पास कर सकूं। हालांकि यह ओवरकिल जैसा लगता है, और मुझे नहीं पता कि गतिविधि को कैसे लिखना चाहिए ToParcel () / readFromParcel ()।

क्या कोई आसान या बेहतर तरीका है? किसी भी मदद के लिए धन्यवाद।

संपादित करें:

इस में रुचि रखने वाले किसी भी व्यक्ति के लिए, नमूने निर्देशिका में एआईडीएल के माध्यम से इसे संभालने के लिए Google से नमूना कोड है: /apis/app/RemoteService.java


अन्य टिप्पणियों में उल्लिखित अन्य विधि bindService () का उपयोग करके गतिविधि से सेवा से जुड़ना है और ServiceConnection कॉलबैक में सेवा का एक उदाहरण प्राप्त करना है। जैसा कि यहां बताया गया है http://developer.android.com/guide/components/bound-services.html


अपने ऐप के अंदर localservice से भेजे गए प्रसारण को सुनने के लिए रिसीवर को LocalBroadcastManager करने के लिए LocalBroadcastManager का उपयोग करें, संदर्भ यहां जाता है:

developer.android.com/reference/android/support/v4/content/…


एक कोड उदाहरण के साथ @MrSnowflake उत्तर का पालन करने के लिए। यह अब एक्सएबीबर ओपन सोर्स Application क्लास हैApplication क्लास Listeners और प्रबंधक इंटरफेस को और केंद्रीकृत और समन्वयित कर रही है। सभी प्रकार के प्रबंधकों को गतिशील रूप से लोड किया जाता है। Xabber में शुरू की गई Activity´s रिपोर्ट करेगा कि वे किस प्रकार के Listener हैं। और जब कोई Service शुरू होती है तो इसे Application क्लास में रिपोर्ट करना शुरू होता है। अब एक Activity को एक संदेश भेजने के लिए आपको बस इतना करना है कि आपकी Activity आपको किस प्रकार की आवश्यकता है listener बनने के लिए। OnPause() रजिस्टर / अनग्रेग में। यह Service केवल उस listener लिए Application कक्षा से पूछ सकती है जिसकी बात करने की आवश्यकता है और यदि वहां है तो गतिविधि प्राप्त करने के लिए तैयार है।

Application क्लास के माध्यम से जाकर आप देखेंगे कि इसके बाद एक लूट अधिक चल रहा है।


जैसा कि मधुर द्वारा वर्णित है, आप संचार के लिए बस का उपयोग कर सकते हैं।

बस का उपयोग करने के मामले में आपके पास कुछ विकल्प हैं:

ओटो इवेंट बस लाइब्रेरी (आरएक्सजेवा के पक्ष में बहिष्कृत)

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

ग्रीन रोबोट का इवेंटबस

http://greenrobot.org/eventbus/

एनवाईबीस (आरएक्सबीस, आरएक्सजेवा का उपयोग करके कार्यान्वित किया गया। इवेंटबस के समान ही)

https://github.com/MindorksOpenSource/NYBus


मुझे हैरान है कि किसी ने ओटो इवेंट बस लाइब्रेरी का संदर्भ नहीं दिया है

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

मैं अपने एंड्रॉइड ऐप में इसका इस्तेमाल कर रहा हूं और यह निर्बाध रूप से काम करता है।


मैसेंजर का उपयोग करना एक सेवा और गतिविधि के बीच संवाद करने का एक और आसान तरीका है।

गतिविधि में, संबंधित मैसेंजर के साथ हैंडलर बनाएं। यह आपकी सेवा से संदेशों को संभाल देगा।

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();
}

एपीआई डेमो में एक पूर्ण उदाहरण पाया जा सकता है: MessengerService और MessengerServiceActivity । MyService कैसे काम करता है के लिए पूर्ण उदाहरण देखें।


स्थानीय ब्रॉडकास्ट प्रबंधक के अलावा , इवेंट बस और मैसेंजर ने पहले ही इस प्रश्न में उत्तर दिया है, हम सेवा से संवाद करने के लिए लंबित इरादे का उपयोग कर सकते हैं।

जैसा कि here मेरे ब्लॉग पोस्ट में बताया गया here

सेवा और गतिविधि के बीच संचार लंबित इंटेन्टेंट का उपयोग करके किया जा सकता है। इसके लिए हम createPendingResult () .createPendingResult () का उपयोग कर सकते हैं एक नया लंबित इंटेन्टेंट ऑब्जेक्ट बनाता है जिसे आप उपयोग करने के लिए सेवा के लिए हाथ दे सकते हैं और परिणामस्वरूप डेटा को अपने गतिविधि में वापस भेज सकते हैं AtctivityResult (int, int, इरादा) कॉलबैक। चूंकि एक लंबित इंटेन्टेंट पार्सलबल है, और इसलिए अतिरिक्त इरादे में रखा जा सकता है, तो आपकी गतिविधि सेवा के लिए इस लंबित इंटेन्टेंट को पास कर सकती है। बदले में, सेवा लंबित इंटेंट पर भेजने () विधि को कॉल करने के लिए कॉल कर सकती है घटना के माध्यम से गतिविधि एक घटना के परिणाम।

गतिविधि

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);

                }
            }
        }
    }
}




android-service