सीमित सेवाओं के बारे में खास जानकारी

सीमित सेवा, एक क्लाइंट-सर्वर इंटरफ़ेस में मौजूद सर्वर होती है. इसकी मदद से कॉम्पोनेंट जैसे कि ऐसी गतिविधियाँ जो सेवा से जुड़ी हैं, अनुरोध भेजें, जवाब पाएँ, और इंटरप्रोसेस कम्यूनिकेशन (आईपीसी). एक सीमित सेवा आम तौर पर सिर्फ़ तब काम करती है, जब वह दूसरी के लिए काम करती है ऐप्लिकेशन घटक है और बैकग्राउंड में हमेशा के लिए नहीं चलता है.

इस दस्तावेज़ में बाउंड सेवा बनाने का तरीका और बाइंड करने का तरीका बताया गया है दूसरे ऐप्लिकेशन कॉम्पोनेंट से सेवा में ट्रांसफ़र किया जाता है. सेवाओं के बारे में ज़्यादा जानकारी के लिए, यहां जाएं: सामान्य, जैसे कि किसी सेवा से नोटिफ़िकेशन कैसे डिलीवर करें और सेवा को चलने के लिए सेट कैसे करें देखें, तो सेवाओं के बारे में खास जानकारी.

बुनियादी बातें

सीमित सेवा, Service क्लास को लागू करने की प्रोसेस है. इसकी मदद से अन्य ऐप्लिकेशन उससे बाइंड होते हैं और उससे इंटरैक्ट करते हैं. किसी एक सेवा के लिए, आप onBind() कॉलबैक तरीका लागू करते हैं. यह तरीका, ऐसे प्रोग्रामिंग इंटरफ़ेस को तय करने वाला IBinder ऑब्जेक्ट दिखाता है जो सेवा के साथ इंटरैक्ट करने के लिए क्लाइंट का उपयोग कर सकते हैं.

किसी चालू सेवा से जोड़ें

जैसा कि सेवाओं की खास जानकारी में बताया गया है, आप एक ऐसी सेवा का निर्माण कर सकते हैं जो चालू भी है और सीमित भी. इसका मतलब है कि startService() पर कॉल करके सेवा का इस्तेमाल किया जा सकता है. इसकी मदद से, सेवा अनिश्चित रूप से चलती है. आप क्लाइंट को इन तरीकों से भी सेवा से जुड़ने की अनुमति दे सकते हैं bindService() पर कॉल किया जा रहा है.

अगर आपने सेवा शुरू की और उसे सीमित तौर पर शुरू किया, तो सेवा शुरू होने पर, जब सभी क्लाइंट की सेवा बंद हो जाती है, तो सिस्टम सेवा को बंद नहीं करता. इसके बजाय, आपको stopSelf() या stopService() पर कॉल करके सेवा को साफ़ तौर पर रोकें.

आम तौर पर, onBind() में से किसी एक को ही लागू किया जाता है या onStartCommand(), कभी-कभी ऐसा हो सकता है इसके लिए ज़रूरी है दोनों लागू करें. उदाहरण के लिए, कोई म्यूज़िक प्लेयर अपनी सेवा को चलने देने के लिए काम का हो सकता है अनिश्चितता तक और बाइंडिंग भी उपलब्ध कराएं. इस तरह से, कोई गतिविधि शुरू होने पर, और संगीत, उपयोगकर्ता के ऐप्लिकेशन छोड़ने के बाद भी चलता रहेगा. इसके बाद, जब उपयोगकर्ता ऐप्लिकेशन पर वापस आने पर, गतिविधि का कंट्रोल फिर से पाने के लिए, गतिविधि को सेवा से जोड़ा जा सकता है प्लेबैक.

किसी शुरू की गई सेवा में बाइंडिंग जोड़ते समय, सेवा की लाइफ़साइकल के बारे में ज़्यादा जानकारी के लिए, किसी सीमित सेवा की लाइफ़साइकल को मैनेज करना सेक्शन देखें.

क्लाइंट कॉल करके किसी सेवा से जुड़ना bindService(). अगर ऐसा होता है, तो ServiceConnection को लागू करने की सुविधा देता है, जो सेवा के साथ कनेक्शन पर नज़र रखता है. इसकी रिटर्न वैल्यू bindService() से पता चलता है कि मौजूद है और क्लाइंट के पास इसका ऐक्सेस है या नहीं.

टास्क कब शुरू होगा Android सिस्टम क्लाइंट और सेवा के बीच कनेक्शन बनाता है, तो onServiceConnected() को कॉल करता है ServiceConnection पर. कॉन्टेंट बनाने onServiceConnected() तरीके में IBinder शामिल है तर्क है, जिसका इस्तेमाल क्लाइंट बाउंड सेवा से संपर्क करने के लिए करता है.

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

जब आखिरी क्लाइंट सेवा से अलग होता है, तो सिस्टम सेवा को खत्म कर देता है. हालांकि, ऐसा तब ही होता है, जब सेवा, startService() का इस्तेमाल करके शुरू की गई थी.

इंटरफ़ेस को तय करना, सेवाओं को सीमित तौर पर लागू करने की आपकी सुविधा का सबसे अहम हिस्सा है यह जानकारी देता है कि आपका onBind() कॉलबैक तरीका दिखाता है. नीचे दिए गए इस अनुभाग में ऐसे कई तरीकों पर चर्चा की गई है, जिनसे आप अपनी सेवा IBinder इंटरफ़ेस.

सीमित सेवा बनाएं

बाइंडिंग उपलब्ध कराने वाली सेवा बनाते समय, आपको IBinder देना होगा जिसकी मदद से एक प्रोग्रामिंग इंटरफ़ेस उपलब्ध कराया जाता है. इसका इस्तेमाल करके, क्लाइंट सेवा से इंटरैक्ट कर सकते हैं. यह लीजिए इंटरफ़ेस को परिभाषित करने के तीन तरीके हैं:

बाइंडर क्लास को बढ़ाना
अगर आपकी सेवा आपके ऐप्लिकेशन के लिए निजी है और उसी प्रक्रिया में चलती है का इस्तेमाल करके अपना इंटरफ़ेस बनाएं. यह आम बात है. Binder क्लास और उसका एक इंस्टेंस से वापस करता है onBind(). क्लाइंट को Binder मिलता है और इसका इस्तेमाल, Binder में उपलब्ध सार्वजनिक तरीकों को सीधे ऐक्सेस करने के लिए कर सकता है लागू करना या Service.

यह पसंदीदा तकनीक है, जब आपकी सेवा सिर्फ़ आपके लिए बैकग्राउंड वर्कर के तौर पर काम करती है का इस्तेमाल करें. जब यह इंटरफ़ेस बनाने का पसंदीदा तरीका नहीं है, तो इसका इस्तेमाल सिर्फ़ यह होगा अगर आपकी सेवा का इस्तेमाल दूसरे ऐप्लिकेशन या अलग-अलग प्रोसेस में किया जाता है.

मैसेंजर का इस्तेमाल करना
अगर आपको अलग-अलग प्रोसेस पर अपना इंटरफ़ेस काम करना है, तो Messenger वाली सेवा के लिए इंटरफ़ेस. इस तरह, सेवा में Handler के बारे में बताता है, जो अलग-अलग तरह के Message ऑब्जेक्ट के रिस्पॉन्स देता है.

यह Handler Messenger की बुनियाद है, जो IBinder को शेयर कर सकता है इससे क्लाइंट को Message ऑब्जेक्ट का इस्तेमाल करके, सेवा को निर्देश भेजने की अनुमति मिलती है. इसके अलावा, क्लाइंट इसका Messenger तय कर सकता है वह अपनी निजी जगह सही नहीं होती, इसलिए सेवा आपके मैसेज को वापस भेज सकती है.

इंटरप्रोसेस कम्यूनिकेशन (आईपीसी) करने का यह सबसे आसान तरीका है, क्योंकि Messenger सभी अनुरोधों को एक ही थ्रेड में ले जाता है, ताकि आपको डिज़ाइन करने की ज़रूरत न पड़े ताकि आपकी सेवा थ्रेड-सुरक्षित रहे.

एआईडीएल का इस्तेमाल करना
Android इंटरफ़ेस डेफ़िनिशन लैंग्वेज (एआईडीएल), ऑब्जेक्ट को डीकंपोज़ करती है ऐसे प्रिमिटिव जिन्हें ऑपरेटिंग सिस्टम समझ सकता है. साथ ही, परफ़ॉर्म करने के लिए उन्हें कई प्रोसेस के साथ इकट्ठा करता है आईपीसी. Messenger का इस्तेमाल करने वाली पिछली तकनीक, असल में एआईडीएल पर आधारित है बुनियादी स्ट्रक्चर.

जैसा कि पिछले सेक्शन में बताया गया है, Messenger हर सभी क्लाइंट अनुरोधों को एक ही थ्रेड में करते हैं, ताकि सेवा को एक-एक करके अनुरोध मिलें. अगर, हालांकि, आपको यह भी सेट करना है कि आपकी सेवा एक साथ कई अनुरोधों को मैनेज करे. इसके लिए, एआईडीएल का इस्तेमाल किया जा सकता है सकता है. ऐसे मामले में, आपकी सेवा थ्रेड-सुरक्षित होनी चाहिए और उसमें एक से ज़्यादा थ्रेड की सुविधा होनी चाहिए.

सीधे एआईडीएल का इस्तेमाल करने के लिए, प्रोग्रामिंग इंटरफ़ेस को परिभाषित करने वाली एक .aidl फ़ाइल बनाएगा. Android SDK टूल, इस फ़ाइल में एक ऐब्स्ट्रैक्ट क्लास जनरेट होगी, जो इंटरफ़ेस को लागू करती है और आईपीसी को हैंडल करती है. अपनी सेवा में आगे बढ़ सकते हैं.

ध्यान दें: ज़्यादातर ऐप्लिकेशन के लिए, एआईडीएल का इस्तेमाल करना सही नहीं होता है सीमित सेवा को सेट अप करना है, क्योंकि इसके लिए मल्टीथ्रेडिंग की क्षमताओं की ज़रूरत पड़ सकती है और तो इसे लागू करना ज़्यादा जटिल हो सकता है. इसलिए, इस दस्तावेज़ में अपनी सेवा के लिए इसका इस्तेमाल कर सकें. अगर आपको यकीन है कि आपको सीधे एआईडीएल का इस्तेमाल करने के लिए, एआईडीएल देखें दस्तावेज़.

बाइंडर क्लास को बढ़ाएं

अगर सिर्फ़ लोकल ऐप्लिकेशन आपकी सेवा का इस्तेमाल करता है और उसे अलग-अलग तरह की टेक्नोलॉजी पर काम करते हैं. इसके बाद, अपनी Binder क्लास लागू की जा सकती है. इससे आपका क्लाइंट डायरेक्ट सेवा में सार्वजनिक तरीकों का ऐक्सेस दे.

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

इसे सेट अप करने का तरीका यहां बताया गया है:

  1. अपनी सेवा में, Binder का ऐसा इंस्टेंस बनाएं जो इनमें से एक:
    • इसमें ऐसे सार्वजनिक तरीके शामिल होते हैं जिन्हें क्लाइंट कॉल कर सकता है.
    • मौजूदा Service इंस्टेंस दिखाता है, जिसमें सार्वजनिक तरीके से क्लाइंट कॉल कर सकता है.
    • सार्वजनिक विधियों से सेवा के ज़रिए होस्ट की गई किसी अन्य क्लास का इंस्टेंस लौटाता है क्लाइंट कॉल कर सकता है.
  2. Binder के इस इंस्टेंस को, onBind() कॉलबैक तरीके से दिखाएं.
  3. क्लाइंट में, onServiceConnected() कॉलबैक तरीके से Binder पाएं और दिए गए तरीकों का इस्तेमाल करके बाउंड सेवा को कॉल करें.

ध्यान दें: सेवा और क्लाइंट, दोनों एक ही होने चाहिए ताकि क्लाइंट, लौटाए गए ऑब्जेक्ट को कास्ट कर सके और उसके एपीआई को सही तरीके से कॉल कर सके. सेवा और क्लाइंट भी उसी प्रक्रिया में होना चाहिए, क्योंकि यह तकनीक कोई काम चीज़ों को एक जगह से दूसरी जगह ले जाते हैं.

उदाहरण के लिए, यहां एक सेवा दी गई है जो क्लाइंट को Binder को लागू करने का तरीका:

Kotlin

class LocalService : Service() {
    // Binder given to clients.
    private val binder = LocalBinder()

    // Random number generator.
    private val mGenerator = Random()

    /** Method for clients.  */
    val randomNumber: Int
        get() = mGenerator.nextInt(100)

    /**
     * Class used for the client Binder. Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    inner class LocalBinder : Binder() {
        // Return this instance of LocalService so clients can call public methods.
        fun getService(): LocalService = this@LocalService
    }

    override fun onBind(intent: Intent): IBinder {
        return binder
    }
}

Java

public class LocalService extends Service {
    // Binder given to clients.
    private final IBinder binder = new LocalBinder();
    // Random number generator.
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods.
            return LocalService.this;
        }
    }

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

    /** Method for clients. */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

LocalBinder, क्लाइंट को getService() तरीका उपलब्ध कराता है, ताकि LocalService का मौजूदा इंस्टेंस. इससे क्लाइंट इसमें सार्वजनिक तरीकों से कॉल कर सकते हैं: सेवा. उदाहरण के लिए, क्लाइंट इस सेवा से getRandomNumber() को कॉल कर सकते हैं.

यहां दी गई गतिविधि, LocalService से जुड़ी है और getRandomNumber() को कॉल करती है जब किसी बटन पर क्लिक किया जाता है:

Kotlin

class BindingActivity : Activity() {
    private lateinit var mService: LocalService
    private var mBound: Boolean = false

    /** Defines callbacks for service binding, passed to bindService().  */
    private val connection = object : ServiceConnection {

        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance.
            val binder = service as LocalService.LocalBinder
            mService = binder.getService()
            mBound = true
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            mBound = false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }

    override fun onStart() {
        super.onStart()
        // Bind to LocalService.
        Intent(this, LocalService::class.java).also { intent ->
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }
    }

    override fun onStop() {
        super.onStop()
        unbindService(connection)
        mBound = false
    }

    /** Called when a button is clicked (the button in the layout file attaches to
     * this method with the android:onClick attribute).  */
    fun onButtonClick(v: View) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call is something that might hang, then put this request
            // in a separate thread to avoid slowing down the activity performance.
            val num: Int = mService.randomNumber
            Toast.makeText(this, "number: $num", Toast.LENGTH_SHORT).show()
        }
    }
}

Java

public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService.
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unbindService(connection);
        mBound = false;
    }

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute). */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call is something that might hang, then put this request
            // in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    /** Defines callbacks for service binding, passed to bindService(). */
    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance.
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

पिछला नमूना दिखाता है कि क्लाइंट, ServiceConnection और onServiceConnected() कॉलबैक. अगला सेक्शन में, सेवा से लिंक करने की इस प्रोसेस के बारे में ज़्यादा जानकारी दी गई है.

ध्यान दें: पिछले उदाहरण में, onStop() तरीका, क्लाइंट को सेवा से बाइंड नहीं करता. जैसा कि ज़्यादा नोट सेक्शन.

और नमूना कोड के लिए, LocalService.java क्लास और ApiDemos में LocalServiceActivities.java क्लास.

मैसेंजर का उपयोग करना

अगर आपको रिमोट प्रोसेस से कम्यूनिकेट करने के लिए अपनी सेवा की ज़रूरत है, तो अपनी सेवा का इंटरफ़ेस उपलब्ध कराने के लिए, Messenger. इस तकनीक से तो आपको एआईडीएल का इस्तेमाल किए बिना इंटरप्रोसेस कम्यूनिकेशन (आईपीसी) का इस्तेमाल करना होगा.

आपके इंटरफ़ेस के लिए Messenger का इस्तेमाल करना है यह एआईडीएल का इस्तेमाल करने से आसान है, क्योंकि इसमें Messenger क्यू सेवा को किए गए सभी कॉल. पूरी तरह से एआईडीएल इंटरफ़ेस सेवा है, जिसे मल्टीथ्रेडिंग को हैंडल करना चाहिए.

ज़्यादातर ऐप्लिकेशन के लिए, सेवा को मल्टीथ्रेडिंग की ज़रूरत नहीं होती. इसलिए, Messenger का इस्तेमाल करने से सेवा एक समय पर एक ही कॉल हैंडल कर पाती है. अगर यह ज़रूरी हो अगर आपकी सेवा मल्टीथ्रेड है, तो अपना इंटरफ़ेस तय करने के लिए AIDL का इस्तेमाल करें.

यहां Messenger को इस्तेमाल करने का तरीका बताया गया है:

  1. यह सेवा एक Handler लागू करती है, जिसमें हर एक के लिए कॉलबैक मिलता है किसी क्लाइंट का कॉल आ रहा है.
  2. Messenger बनाने के लिए, यह सेवा Handler का इस्तेमाल करती है ऑब्जेक्ट (जो Handler का रेफ़रंस है).
  3. Messenger एक IBinder बनाता है, जिसे यह सेवा onBind() से क्लाइंट को वापस लौटा देता है.
  4. Messenger को इंस्टैंशिएट करने के लिए, क्लाइंट IBinder का इस्तेमाल करते हैं (जो सेवा के Handler का संदर्भ देता है), जिसे क्लाइंट भेजने के लिए इस्तेमाल करता है सेवा के लिए Message ऑब्जेक्ट.
  5. सेवा को हर Message अपने Handler में मिलता है—खास तौर पर, handleMessage() तरीके में.

इस तरह, क्लाइंट के पास सेवा पर कॉल करने का कोई तरीका नहीं होता. इसके बजाय, क्लाइंट ऐसे मैसेज (Message ऑब्जेक्ट) डिलीवर करता है जो रिसीव इन Handler.

यहां Messenger इंटरफ़ेस का इस्तेमाल करने वाली सेवा का उदाहरण दिया गया है:

Kotlin

/** Command to the service to display a message.  */
private const val MSG_SAY_HELLO = 1

class MessengerService : Service() {

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    private lateinit var mMessenger: Messenger

    /**
     * Handler of incoming messages from clients.
     */
    internal class IncomingHandler(
            context: Context,
            private val applicationContext: Context = context.applicationContext
    ) : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                MSG_SAY_HELLO ->
                    Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show()
                else -> super.handleMessage(msg)
            }
        }
    }

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    override fun onBind(intent: Intent): IBinder? {
        Toast.makeText(applicationContext, "binding", Toast.LENGTH_SHORT).show()
        mMessenger = Messenger(IncomingHandler(this))
        return mMessenger.binder
    }
}

Java

public class MessengerService extends Service {
    /**
     * Command to the service to display a message.
     */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    static class IncomingHandler extends Handler {
        private Context applicationContext;

        IncomingHandler(Context context) {
            applicationContext = context.getApplicationContext();
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(applicationContext, "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    Messenger mMessenger;

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        mMessenger = new Messenger(new IncomingHandler(this));
        return mMessenger.getBinder();
    }
}

handleMessage() तरीका Handler वह जगह है जहां सेवा को इनकमिंग Message मिलते हैं और तय करता है कि what सदस्य के आधार पर क्या करना है.

क्लाइंट को बस, सेवा से मिले IBinder के आधार पर Messenger बनाना होगा. इसके बाद, send() का इस्तेमाल करके मैसेज भेजना होगा. उदाहरण के लिए, यहां एक गतिविधि को सेवा देता है और इस सेवा को MSG_SAY_HELLO मैसेज डिलीवर करता है:

Kotlin

class ActivityMessenger : Activity() {
    /** Messenger for communicating with the service.  */
    private var mService: Messenger? = null

    /** Flag indicating whether we have called bind on the service.  */
    private var bound: Boolean = false

    /**
     * Class for interacting with the main interface of the service.
     */
    private val mConnection = object : ServiceConnection {

        override fun onServiceConnected(className: ComponentName, service: IBinder) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = Messenger(service)
            bound = true
        }

        override fun onServiceDisconnected(className: ComponentName) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected—that is, its process crashed.
            mService = null
            bound = false
        }
    }

    fun sayHello(v: View) {
        if (!bound) return
        // Create and send a message to the service, using a supported 'what' value.
        val msg: Message = Message.obtain(null, MSG_SAY_HELLO, 0, 0)
        try {
            mService?.send(msg)
        } catch (e: RemoteException) {
            e.printStackTrace()
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    }

    override fun onStart() {
        super.onStart()
        // Bind to the service.
        Intent(this, MessengerService::class.java).also { intent ->
            bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
        }
    }

    override fun onStop() {
        super.onStop()
        // Unbind from the service.
        if (bound) {
            unbindService(mConnection)
            bound = false
        }
    }
}

Java

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean bound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            bound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected—that is, its process crashed.
            mService = null;
            bound = false;
        }
    };

    public void sayHello(View v) {
        if (!bound) return;
        // Create and send a message to the service, using a supported 'what' value.
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service.
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service.
        if (bound) {
            unbindService(mConnection);
            bound = false;
        }
    }
}

इस उदाहरण में यह नहीं दिखाया गया है कि सेवा, क्लाइंट को कैसे जवाब दे सकती है. अगर आपको सेवा का जवाब देना है, तो आपको क्लाइंट में एक Messenger भी बनाना होगा. जब क्लाइंट को onServiceConnected() कॉलबैक मिलता है, तो वह उस सेवा को एक Message भेजता है जिसमें replyTo पैरामीटर में क्लाइंट का Messenger send() तरीके का इस्तेमाल करें.

आप MessengerService.java (सेवा) और MessengerServiceActivities.java (क्लाइंट) के सैंपल.

किसी सेवा से बाइंड करें

ऐप्लिकेशन के कॉम्पोनेंट (क्लाइंट), कॉल करके किसी सेवा से जुड़ सकते हैं bindService(). Android फिर सिस्टम, सेवा के onBind() तरीके को कॉल करता है. इससे, इंटरैक्ट करने के लिए IBinder दिखता है सेवा को फिर से शुरू करने के लिए ज़रूरी है.

बाइंडिंग एसिंक्रोनस है और bindService(), IBinder को तुरंत बिना वापस लौटा देता है से संपर्क करने के लिए प्रोत्साहित करें. IBinder पाने के लिए, क्लाइंट को ServiceConnection का इंस्टेंस जोड़ना है और इसे bindService() को पास करना है. ServiceConnection में एक कॉलबैक तरीका शामिल होता है, जो IBinder को डिलीवर करने के लिए सिस्टम कॉल.

ध्यान दें: सिर्फ़ गतिविधियों, सेवाओं, और कॉन्टेंट देने वालों को ही बाइंड किया जा सकता है किसी सेवा के लिए बाइंड नहीं किया जा सकता.

अपने क्लाइंट की किसी सेवा से जुड़ने के लिए, यह तरीका अपनाएं:

  1. ServiceConnection लागू करें.

    आपके लागू करने के तरीके को दो कॉलबैक तरीकों को ओवरराइड करना होगा:

    onServiceConnected()
    सिस्टम इसे कॉल करके IBinder को डिलीवर करता है सेवा की onBind() तरीका.
    onServiceDisconnected()
    Android सिस्टम इसे तब कॉल करता है, जब सेवा का कनेक्शन अचानक होता है खो जाता है, जैसे कि सेवा क्रैश हो जाती है या खत्म हो जाती है. यह नहीं है तब कॉल किया, जब क्लाइंट की सहमति रद्द की जाती है.
  2. ServiceConnection लागू करने का अनुरोध पास करके, bindService() को कॉल करें.

    ध्यान दें: अगर यह तरीका 'गलत' दिखाता है, तो क्लाइंट के पास सेवा से कोई मान्य कनेक्शन नहीं है. हालांकि, unbindService() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है आपके क्लाइंट को सूचित करता है. अगर ऐसा नहीं है, तो आपका क्लाइंट उस सेवा को डिवाइस कुछ समय से इस्तेमाल में न होने पर, अपने-आप बंद हो जाए.

  3. जब सिस्टम आपके onServiceConnected() कॉलबैक तरीके को कॉल करता है, तो सेवा को कॉल करना शुरू किया जा सकता है. इसके लिए, इनका इस्तेमाल करें: इंटरफ़ेस में बताए गए तरीकों का इस्तेमाल करता है.
  4. सेवा से डिसकनेक्ट करने के लिए, unbindService() पर कॉल करें.

    अगर आपका ऐप्लिकेशन, क्लाइंट को बंद कर देता है और फिर भी आपका क्लाइंट किसी सेवा से बाध्य है, तो ऐप्लिकेशन की तबाही की वजह से क्लाइंट बाइंड नहीं करता. बेहतर तरीका यह है कि ऐसा होते ही क्लाइंट का कानूनी समझौता खत्म कर दिया जाए सेवा के साथ इंटरैक्ट कर रहे हों. ऐसा करने से, कुछ समय से इस्तेमाल न होने वाली सेवा बंद हो जाएगी. Reader Revenue Manager को सेट अप करने के बारे में बाइंडिंग और बाइंडिंग को रोकने के सही समय के बारे में जानने के लिए, ज़्यादा जानकारी सेक्शन देखें.

नीचे दिए गए उदाहरण में क्लाइंट को उस सेवा से कनेक्ट किया गया है जिसे पहले बनाई गई थी बाइंडर क्लास को बढ़ाना, ताकि इसके लिए सिर्फ़ रिटर्न को कास्ट करना IBinder को LocalBinder क्लास में जोड़ें और LocalService इंस्टेंस का अनुरोध करें:

Kotlin

var mService: LocalService

val mConnection = object : ServiceConnection {
    // Called when the connection with the service is established.
    override fun onServiceConnected(className: ComponentName, service: IBinder) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        val binder = service as LocalService.LocalBinder
        mService = binder.getService()
        mBound = true
    }

    // Called when the connection with the service disconnects unexpectedly.
    override fun onServiceDisconnected(className: ComponentName) {
        Log.e(TAG, "onServiceDisconnected")
        mBound = false
    }
}

Java

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established.
    public void onServiceConnected(ComponentName className, IBinder service) {
        // Because we have bound to an explicit
        // service that is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    // Called when the connection with the service disconnects unexpectedly.
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "onServiceDisconnected");
        mBound = false;
    }
};

इस ServiceConnection का इस्तेमाल करके, क्लाइंट किसी सेवा से जुड़ सकता है पास करके इसे bindService() तक करें, जैसा कि इस उदाहरण में दिखाया गया है:

Kotlin

Intent(this, LocalService::class.java).also { intent ->
    bindService(intent, connection, Context.BIND_AUTO_CREATE)
}

Java

Intent intent = new Intent(this, LocalService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
  • bindService() का पहला पैरामीटर Intent जो बाइंड करने के लिए सेवा को साफ़ तौर पर नाम देता है.

    चेतावनी: अगर आप किसी Service, पक्का करें कि आपका ऐप्लिकेशन सुरक्षित हो. इसके लिए, अश्लील कॉन्टेंट का इस्तेमाल करें इंटेंट. किसी सेवा को शुरू करने के लिए इंप्लिसिट इंटेंट का इस्तेमाल करना सुरक्षा के लिए खतरा हो सकता है, क्योंकि आपको पक्के तौर पर पता नहीं है कि सेवा के मकसद के बारे में कौनसी जानकारी दी जा रही है, और उपयोगकर्ता यह नहीं देख सकता कि कौन-सी सेवा शुरू होती है. Android 5.0 (एपीआई लेवल 21) से शुरू करके, सिस्टम bindService() को कॉल करने पर अपवाद दिखता है इंप्लिसिट इंटेंट से.

  • दूसरा पैरामीटर, ServiceConnection ऑब्जेक्ट है.
  • तीसरा पैरामीटर ऐसा फ़्लैग है जो बाइंडिंग के लिए विकल्पों को दिखाता है. आम तौर पर, अगर सेवा पहले से नहीं है, तो बाइंडिंग के लिए विकल्प BIND_AUTO_CREATE होते हैं. ज़िंदा है. अन्य संभावित वैल्यू ये हैं: BIND_DEBUG_UNBIND, BIND_NOT_FOREGROUND या बिना किसी शुल्क के 0.

अतिरिक्त नोट

किसी सेवा का इस्तेमाल करने के बारे में यहां कुछ ज़रूरी बातें बताई गई हैं:

  • हमेशा DeadObjectException अपवादों को ट्रैप में रखें, जिन्हें फेंक दिया जाता है जब कनेक्शन टूट जाता है. रिमोट तरीकों से सिर्फ़ यही अपवाद होता है.
  • ऑब्जेक्ट, सभी प्रोसेस में रेफ़रंस के तौर पर गिने जाते हैं.
  • आम तौर पर, बाइंडिंग और अनबाइंडिंग को इस दौरान पेयर किया जाता है क्लाइंट के लाइफ़साइकल के हिसाब से, प्रॉडक्ट के बारे में जानकारी देता है. ये उदाहरण देखें:
    • अगर आपको अपनी गतिविधि के दिखने के दौरान ही सेवा का इस्तेमाल करना है, तो onStart() के दौरान इसे लिंक करें और onStop() के दौरान इसका इस्तेमाल बंद करें.
    • अगर आप चाहते हैं कि आपकी गतिविधि के रुक जाने पर भी उसे जवाब मिले, तो बैकग्राउंड, onCreate() के दौरान बाइंड करें और हटाएं onDestroy() के दौरान. ध्यान रहे कि इसका मतलब है कि गतिविधि को उसके चलने के दौरान सेवा का उपयोग करने की आवश्यकता हो, भले ही वह बैकग्राउंड में क्यों न चल रही हो, इसलिए जब सेवा किसी अन्य प्रक्रिया में है, तो आप इस प्रक्रिया का महत्व बढ़ा देते हैं और यह को सिस्टम से मरने की संभावना बढ़ जाती है.

    ध्यान दें: आम तौर पर, आप बाइंड और लिंक नहीं करते हैं नहीं आपकी गतिविधि के onResume() और onPause() कॉलबैक के दौरान, क्योंकि ये कॉलबैक प्रत्येक लाइफ़साइकल ट्रांज़िशन. इन ट्रांज़िशन के दौरान होने वाली प्रोसेसिंग को कम से कम रखें.

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

किसी सेवा से बाइंड करने का तरीका दिखाने वाले और सैंपल कोड के लिए, ApiDemos में RemoteService.java क्लास.

सीमित सेवा की लाइफ़साइकल मैनेज करें

जब कोई सेवा सभी क्लाइंट के लिए उपलब्ध नहीं होती है, तो Android सिस्टम उसे बंद कर देता है (जब तक कि इसे startService()). इसलिए, आपको अपनी सेवा का लाइफ़साइकल मैनेज करने की ज़रूरत नहीं है, अगर वह केवल एक सीमित सेवा है. Android सिस्टम, अन्य चीज़ों के आधार पर आपके लिए इसे मैनेज करता है फिर चाहे वह किसी क्लाइंट तक सीमित हो.

हालांकि, अगर आपने onStartCommand() कॉलबैक तरीका लागू करने का विकल्प चुना है, तो आपको सेवा को साफ़ तौर पर बंद करना होगा, क्योंकि सेवा को अब शुरू मान लिया गया है. इस स्थिति में, सेवा तब तक चलती है, जब तक कि खुद को stopSelf() या किसी दूसरे कॉम्पोनेंट stopService() के साथ रोकता है, भले ही वह किसी क्लाइंट.

इसके अलावा, अगर आपकी सेवा शुरू हो गई है और बाइंडिंग स्वीकार करती है, तो सिस्टम जब onUnbind() वाला तरीका इस्तेमाल किया है, तो वैकल्पिक तौर पर वापस किया जा सकता है अगर अगली बार किसी क्लाइंट के सेवा से जुड़ने पर, आप onRebind() पर कॉल पाना चाहते हैं, तो true. onRebind() अमान्य वैल्यू दिखाता है, लेकिन क्लाइंट को अब भी IBinder onServiceConnected() कॉलबैक. नीचे दिए गए डायग्राम में, इस तरह के लाइफ़साइकल के लिए लॉजिक को दिखाया गया है.

पहला डायग्राम. शुरू की गई सेवा की लाइफ़साइकल और बाइंडिंग की भी अनुमति देती हैं.

शुरू की गई सेवा के लाइफ़साइकल के बारे में ज़्यादा जानने के लिए, सेवाओं के बारे में खास जानकारी देखें.