Android में गतिविधि के लिए बाइंड सेवा


90

मैं एक साधारण मीडिया प्लेयर लिखने की कोशिश कर रहा हूं जो RTSP का उपयोग करके स्ट्रीमिंग ऑडियो चलाता है। मेरे पास एक GUI- गतिविधि और एक सेवा है जो प्लेबैक करती है। मेरा सवाल यह है कि गतिविधि और सेवा के बीच सबसे अच्छा संवाद कैसे किया जाए (जैसे खिलाड़ी राज्य के आधार पर जीयूआई को अपडेट करना)।

मुझे पता है कि मैं onBind () का उपयोग करके सेवा को सेवा से बांध सकता हूं, लेकिन अगर मैं सही ढंग से समझता हूं तो गतिविधि के मारे जाने पर यह सेवा बंद हो जाएगी। मैं प्लेबैक को जारी रखना चाहता हूं, भले ही उपयोगकर्ता गतिविधि से बाहर निकल जाए। क्या इस समस्या से निपटने का कोई मानक या पसंदीदा तरीका है?

जवाबों:


154

"यदि आप startService(..)उस सेवा के साथ एक Android सेवा शुरू करते हैं, जब तक कि आप स्पष्ट रूप से आह्वान नहीं करते हैं, तब तक सेवा चलती रहेगी stopService(..)। दो कारण हैं कि एक सेवा को सिस्टम द्वारा चलाया जा सकता है। यदि कोई व्यक्ति कॉल करता है, Context.startService()तो सिस्टम सेवा को पुनः प्राप्त करेगा (इसे बनाएगा और इसकी onCreate()विधि को कॉल करेगा यदि जरूरत है) और फिर अपने फोन onStartCommand(Intent, int, int)तर्क ग्राहक द्वारा आपूर्ति के साथ विधि। सेवा करेंगे इस बिंदु पर जब तक प्रदर्शन जारी रहे, Context.stopService()या stopSelf()कहा जाता है। ध्यान दें कि कई कॉल करने के लिए Context.startService()घोंसला नहीं है (हालांकि वे कई इसी के लिए कॉल में परिणाम कर onStartCommand()), इसलिए कोई कोई बात नहीं कितनी बार यह सेवा शुरू की है एक बार बंद कर दिया है Context.stopService()या stopSelf()कहा जाता है, हालांकि, सेवाओं का उपयोग कर सकते हैंstopSelf(int) सेवा को सुनिश्चित करने की विधि तब तक बंद नहीं की जाती है जब तक कि इंटेंट को संसाधित नहीं किया जाता है।

ग्राहक Context.bindService()किसी सेवा के लिए लगातार कनेक्शन प्राप्त करने के लिए भी उपयोग कर सकते हैं । यह वैसे ही सेवा बनाता है यदि यह पहले से ही नहीं चल रहा है ( onCreate()ऐसा करते समय कॉलिंग ), लेकिन कॉल नहीं करता है onStartCommand()। क्लाइंट को वह IBinderवस्तु प्राप्त होगी जो सेवा अपने onBind(Intent)तरीके से वापस आती है , जिससे ग्राहक को फिर से सेवा में कॉल करने की अनुमति मिलती है। जब तक कनेक्शन स्थापित है (चाहे ग्राहक सेवा पर एक संदर्भ रखता है IBinder) तब तक सेवा चालू रहेगी । आमतौर पर IBinderलौटा एक जटिल इंटरफ़ेस के लिए है जिसे एआईडीएल में लिखा गया है।

एक सेवा दोनों शुरू की जा सकती है और इसके लिए बाध्य कनेक्शन हो सकते हैं। ऐसे मामले में, सिस्टम सेवा को तब तक चालू रखेगा जब तक या तो इसे शुरू किया जाता है या Context.BIND_AUTO_CREATEध्वज के साथ इसके एक या अधिक कनेक्शन होते हैं । एक बार जब इनमें से कोई भी स्थिति पकड़ में नहीं आती है, तो सेवा का onDestroy()तरीका कहा जाता है और सेवा को प्रभावी रूप से समाप्त कर दिया जाता है। सभी क्लीनअप (थ्रेड्स को अनरजिस्टर्ड रिसीवर्स को रोकना) से लौटने पर पूरा होना चाहिए onDestroy()। "


1
थोड़ा भ्रम: क्या यह सच है कि अगर गतिविधि नष्ट हो जाती है तो सेवा भी नष्ट हो जाएगी? या क्या वह सेवा केवल तब ही नष्ट नहीं होती जब मैं अपना स्वयं का एआईडीएल लागू करता हूं? मैं पूछ रहा हूँ क्योंकि जब मैं startService (IntentService पर esp) का उपयोग करता हूं, तो सेवा बंद हो जाती है जब इसका काम गतिविधि के विपरीत हो जाता है जब गतिविधि मर जाती है। तो क्या यह सच है कि यदि गतिविधि मर जाती है, तो जो सेवा बाध्य है (विशेष रूप से) वह भी मर जाती है?
केट्रेडल पिलोन

1
यदि आप startService को कॉल करके सरल सर्वर का उपयोग कर रहे हैं तो तब तक सेवा बंद नहीं होगी जब तक आप stopSelf () या stopService () को कॉल नहीं करते हैं। और अगर आप bindService का उपयोग करते हैं तो अगला, हाँ सेवा मर जाएगी यदि सभी जुड़े / बाँध घटक नष्ट हो जाते हैं।
आसिफ मुश्ताक

1
@UnKnown यदि सेवा को startService () का उपयोग करना शुरू किया जाता है, तो कोई फर्क नहीं पड़ता कि आप इसे बाँधते हैं या इसे अनबाइंड करते हैं, यह चलता रहेगा और इसे केवल stopService () या stopSelf () कहकर नष्ट किया जा सकता है। इसलिए, भले ही सेवा से जुड़ी गतिविधि नष्ट हो गई हो, सेवा नष्ट नहीं होगी।
CopsOnRoad

क्या आप मुझे इस प्रश्न के लिए मदद कर सकते हैं stackoverflow.com/questions/51508046/…
राजेश के

25

सबसे पहले, 2 बात जो हमें समझने की जरूरत है

ग्राहक

  • यह विशिष्ट सर्वर से अनुरोध करता है

    bindService(new 
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

यहाँ कक्षा mServiceConnका उदाहरण है ServiceConnection(इनबिल्ट) यह वास्तव में इंटरफ़ेस है जिसे हमें नेटवर्क कनेक्शन स्थिति की निगरानी के लिए दो (1 नेटवर्क कनेक्टेड और 2 नेटवर्क कनेक्टेड नहीं है) विधि के साथ लागू करने की आवश्यकता है।

सर्वर

  • यह क्लाइंट के अनुरोध को संभालता है और इसकी प्रतिकृति बनाता है जो ग्राहक के लिए निजी है जो केवल अनुरोध भेजता है और सर्वर की यह प्रतिकृति विभिन्न थ्रेड पर चलती है।

अब क्लाइंट की ओर से, सर्वर की सभी विधि का उपयोग कैसे करें?

  • सर्वर IBind Object.so के साथ प्रतिक्रिया भेजता है। IBind ऑब्जेक्ट हमारा हैंडलर है जो (।) ऑपरेटर का उपयोग करके सेवा की सभी विधि तक पहुंचता है।

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

अब कैसे कॉल विधि है जो सेवा में निहित है

myservice.serviceMethod();

यहाँ myServiceवस्तु है और serviceMethodeसेवा में विधि है। और इस तरह से क्लाइंट और सर्वर के बीच संचार स्थापित होता है।


10

मैंने फोन करने की कोशिश की

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

फलस्वरूप और मैं एक चिपचिपी सेवा बना सकता था और उसे बाँध सकता था। बाउंड सर्विस उदाहरण के लिए विस्तृत ट्यूटोरियल ।


5

एक विधि है जिसे unbindService कहा जाता है जो एक ServiceConnection लेगा जिसे आपने bindService के नाम से बनाया होगा। यह आपको सेवा से डिस्कनेक्ट करने की अनुमति देगा जबकि अभी भी यह चल रहा है।

जब आप इसे फिर से कनेक्ट करते हैं तो यह एक समस्या पैदा कर सकता है, क्योंकि आप शायद यह नहीं जानते कि यह चल रहा है या नहीं जब आप फिर से गतिविधि शुरू करते हैं, तो आपको अपने गतिविधि कोड में इस पर विचार करना होगा।

सौभाग्य!


-1

यह एक पक्षपाती जवाब है, लेकिन मैंने एक लाइब्रेरी लिखी है जो एंड्रॉइड सर्विसेज के उपयोग को आसान बना सकती है, अगर वे स्थानीय रूप से ऐप के समान प्रक्रिया में चलते हैं: https://github.com/germnix/acacia

मूल रूप से आप @ सेवा और इसके कार्यान्वयन वर्ग के साथ एनोटेट किए गए इंटरफ़ेस को परिभाषित करते हैं, और लाइब्रेरी सेवा को बनाता है और बांधता है, कनेक्शन और पृष्ठभूमि कार्यकर्ता धागा को संभालता है:

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

आप संबंधित सूचनाओं को छिपाने / दिखाने के लिए संबंधित android.app.Service का एक उदाहरण प्राप्त कर सकते हैं, अपनी खुद की android.app.Service का उपयोग करें और यदि आप चाहें तो मैन्युअल रूप से थ्रेडिंग को संभाल सकते हैं।


-5

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


यदि आपका IDE स्वचालित रूप से एक बनाता है, तो आपको फ़ंक्शन को ओवरराइड करना होगा और सुपरक्लास के onDestroy () को डिफ़ॉल्ट कॉल को हटाना होगा। लेकिन आप कभी ऐसा क्यों करना चाहेंगे?
रिप्टीडे ४
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.