सवाल एक प्रारंभ और बाध्य सेवा कब नष्ट हो जाती है?


जब मैंने दो विरोधाभासी बिंदुओं को देखा तो मैं एंड्रॉइड में सेवा प्रलेखन के माध्यम से जा रहा था:

सेवा दस्तावेज़ में यह निर्दिष्ट है एक सेवा के जीवन चक्र का प्रबंधन

ये दो पथ पूरी तरह से अलग नहीं हैं। यही है, आप एक से बांध सकते हैं   सेवा जो प्रारंभ सेवा () के साथ पहले ही शुरू हो चुकी थी। उदाहरण के लिए, ए   startService () को कॉल करके पृष्ठभूमि संगीत सेवा शुरू की जा सकती है   एक इरादा जो संगीत को खेलने के लिए पहचानता है। बाद में, संभवतः कब   उपयोगकर्ता खिलाड़ी पर कुछ नियंत्रण करना चाहता है या प्राप्त करना चाहता है   वर्तमान गीत के बारे में जानकारी, एक गतिविधि से बांध सकते हैं   bindService () को कॉल करके सेवा। इस तरह के मामलों में, stopService () या   stopSelf () वास्तव में सभी ग्राहकों तक सेवा को रोक नहीं देता है   निकल।

लेकिन दस्तावेज़ में बाध्य सेवाओं के बारे में एक बाउंड सेवा के जीवन चक्र का प्रबंधन

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

यह मुझे हो सकता है लेकिन मुझे लगता है कि बयान विरोधाभासी हैं। क्या कोई भी स्पष्टीकरण दे सकता है ...


44
2018-06-17 11:50


मूल




जवाब:


दरअसल, दोनों पैराग्राफ एक-दूसरे के पूरक होते हैं (हालांकि उनका शब्द गुमराह हो सकता है), और दोनों पैराग्राफ दस्तावेज से छवि के अनुरूप हैं। चलो देखते हैं:

ये दो पथ पूरी तरह से अलग नहीं हैं। यही है, आप एक सेवा से जुड़ सकते हैं जो startService () से पहले से शुरू हो चुका था। उदाहरण के लिए, startService () को एक ऐसे इरादे से कॉल करके पृष्ठभूमि संगीत सेवा शुरू की जा सकती है जो संगीत को खेलने के लिए पहचानती है। बाद में, संभवतः जब उपयोगकर्ता खिलाड़ी पर कुछ नियंत्रण करना चाहता है या वर्तमान गीत के बारे में जानकारी प्राप्त करना चाहता है, तो एक गतिविधि bindService () को कॉल करके सेवा से जुड़ सकती है। इस तरह के मामलों में, stopService () या stopSelf () वास्तव में सेवा को तब तक नहीं रोकता जब तक सभी क्लाइंट अनबाइंड न हों।

उत्कृष्टता यह है: यदि आप कोई सेवा शुरू करते हैं, तो उसके लिए क्लाइंट को बाध्य करें, फिर इसे रोकने का प्रयास करें, सभी क्लाइंट को अनबाइंड करने से पहले सेवा बंद नहीं हुई है (नष्ट हो गई है)। दूसरा अनुच्छेद विरोधाभास नहीं करता है, यह इस कथन को परिशोधित करता है।

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

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

Lifecycle for started and bound services


46
2018-06-18 20:19



महान स्पष्टीकरण ... इसे साफ़ करने के लिए धन्यवाद .. - anz
तो, मुझे लगता है कि मैं एक सेवा को अनइंड करना और बंद करना चाहता हूं जो शुरू और बाध्य था, क्या मुझे इसे रोकने से पहले स्टॉप सेवा को कॉल करना चाहिए? या इससे कोई फर्क नहीं पड़ता? - Dielson Sales
इससे कोई फर्क नहीं पड़ता कि आप किस क्रम में करते हैं। सेवा को नष्ट नहीं किया जाएगा इससे पहले कि सभी क्लाइंट अनबाउंड न हों और इसे रोक दिया गया है (जैसा कि आप @ChuckKrutsinger के जवाब में देख सकते हैं)। - Stephan
एक हाइब्रिड सेवा में इस आरेख के अनुसार, सभी ग्राहकों के बाद Unstind onDestroy () को बुलाया जाता है। क्या यह सही है? क्या Unbind () और onDestroy () पर एक सीधा लिंक होना चाहिए? - Amit0191


सहमत हैं कि दस्तावेज़ीकरण स्पष्ट हो सकता है। वे क्या कहने की कोशिश कर रहे हैं:

  • यदि आप startService () को कॉल करते हैं, तो सेवा तब तक चलती रहेगी जब तक आप सेवा के भीतर से StopSerivce () (या stopSelf () को कॉल नहीं करते)
  • यदि आप bindService () को कॉल करते हैं, तो सेवा तब तक चलती रहेगी जब तक आप unbindService ()
  • इसलिए, यदि आप startService () और bindService () दोनों को कॉल करते हैं, तो सेवा तब तक चलती रहेगी जब तक आप दोनों stopService और unbindService () को कॉल न करें। न तो अपनी इच्छानुसार सेवा को रोक देगा।

एक बहुत ही सरल गतिविधि और सेवा बनाई और स्टार्ट / स्टॉप / बाइंड / अनबिंड के निम्नलिखित अनुक्रम चलाए। मैंने देखा कि कॉल ने निम्नलिखित परिणाम दिए हैं।

बाँध-अनबाइंड

bindService() caused:
    onCreate()
    onBind()
unbindService() caused:
    onUnbind()
    onDestroy()

स्टार्ट-बाँध-अनबाइंड-स्टॉप

startService() caused:
    onCreate()
    onStartCommand()
bindService() caused:
    onBind()
unbindService() caused:
    onUnbind()
stopService() caused:
    onDestroy()

शुरू-बाँध-स्टॉप-अनबाइंड

startService() caused:
    onCreate()
    onStartCommand()
bindService() caused:
    onBind()
stopService() caused:
    -- nothing
unbindService() caused:
    onUnbind()
    onDestroy()

बाँध शुरू-स्टॉप-अनबाइंड

bindService() caused:
    onCreate()
    onBind()
startService() caused:
    onStartCommand()
stopService() caused:
    -- nothing -- still running
unbindService() caused:
    onUnbind()
    onDestroy()

BIND रखा शुरू अनबाइंड-स्टॉप

bindService() caused:
    onCreate()
    onBind()
startService() caused:
    onStartCommand()
unbindService() caused:
    onUnbind()
stopService() caused:
    onDestroy()

जैसा कि आप देख सकते हैं, प्रत्येक मामले में जहां दोनों बांधना और शुरू करना कहा जाता था, सेवा तब तक चलती रही जब तक कि दोनों अनइंड और स्टॉप नहीं कहा जाता था। अनबिंड / स्टॉप का अनुक्रम महत्वपूर्ण नहीं है।

यहां उदाहरण कोड है जिसे मेरे सरल परीक्षण ऐप में अलग-अलग बटन से बुलाया गया था:

public void onBindBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

public void onUnbindBtnClick(View view) {
    if (serviceIsBound) {
        unbindService(serviceConnection);
        serviceIsBound = false;
    }
}

public void onStartBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    startService(intent);
}

public void onStopBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    exampleService.stopService(intent);
}

63
2018-06-18 20:31



इस शोध में धन्यवाद के लिए धन्यवाद - anz
महान स्पष्टीकरण ... बहुत मदद की .. धन्यवाद - John
अब तक का सबसे स्पष्ट स्पष्टीकरण। यह दस्तावेज़ों में उपलब्ध होना चाहिए। अच्छा कार्य! - harsh_v
डॉक्टर द्वारा भ्रमित किया गया था: "जब कोई ग्राहक सेवा के साथ बातचीत कर रहा है, तो यह unbindService () को अनबिंड करने के लिए कहता है। जब कोई ग्राहक सेवा से बंधे नहीं होता है, तो सिस्टम सेवा को नष्ट कर देता है।" इस जवाब ने यह स्पष्ट कर दिया कि अविश्वसनीय सेवा के बाद भी एक बाध्य सेवा (Context.BIND_AUTO_CREATE के साथ) जीवित रहेगी। स्वयं को रोकने के बाद ही इसे नष्ट कर दिया जाएगा। यह bindService के समान है, फिर सेवा प्रवाह शुरू करें। धन्यवाद! - lannyf


हाँ, यह काम करता है। मैं एक नमूना कोड के साथ पूरा करना चाहता हूँ:

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

 public class MyActivity extends Activity{

    private MyService myService;
    private boolean mIsBound = false;

    private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder binder) {
            MyService.MyBinder b = (MyService.MyBinder) binder;
            myService = b.getService();
            mIsBound = true
            //Do something
            // Here you can call : myService.aFonctionInMyService();

        }
        public void onServiceDisconnected(ComponentName className) {
            // Do something
            mIsBound = false;
        }
    }



    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        //Checked if my service is running
        if (!isMyServiceRunning()) {
            //if not, I start it.
            startService(new Intent(this,MyService.class));
        }
    }

    private boolean isMyServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager
                .getRunningServices(Integer.MAX_VALUE)) {
            if (MyService.class.getName().equals(
                    service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        doBindService();
    }




    //Connection to the Service
    private void doBindService() {
        bindService(new Intent(this,MyService.class), mConnection,
                Context.BIND_AUTO_CREATE);
    }

    // Disconnection from the service
    private void doUnbindService() {
        if (mIsBound) {
            // Detach our existing connection.
            unbindService(mConnection);
        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        doUnbindService();
        super.onPause();
    }

}


public class MyService extends Service{


    public static String Tag = "MyService";
    private final IBinder mBinder = new MyBinder();

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub      
        super.onCreate();
        Log.d(Tag, "onCreate()");

    }

    public class MyBinder extends Binder {
        public LocationService getService() {
            return LocationService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d(Tag, "onBind()");
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d(Tag, "onUnBind()");
        return super.onUnbind(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.d(Tag,"onStartCommand()");

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        Log.d(Tag, "onDestroy");
        super.onDestroy();
    }

    public void aFonctionInMyService(){
        //Do Something
    }

}

1
2018-02-06 09:57



isMyServiceRunning धीमा है और इसे चालू करें (क्रिएट) गतिविधि खराब अभ्यास है - Simon