android - एप्लिकेशन की मौत होने पर एंड्रॉइड पृष्ठभूमि सेवा पुनरारंभ हो रही है




service background-service (5)

ऐप और सेवा एक ही प्रक्रिया पर रहती है, जिसका मतलब है कि जब ऐप मारे जाते हैं तो आपकी सेवा भी होती है। ऑनस्टार्ट कमांड का रिटर्न वैल्यू बदलना इस प्रक्रिया को प्रभावित नहीं करता है। यह बस सेवा को बताता है कि जब आप इसे बताते हैं या जब इसे पूरा करने की आवश्यकता होती है तो यह समाप्त हो जाता है। जैसा कि आपकी मूल पोस्ट पर आपकी टिप्पणी में बताया गया है, इसे एक अग्रभूमि प्रक्रिया के रूप में स्थापित करने के लिए काम किया है, लेकिन यह वास्तव में समस्या को हल नहीं करने के लिए उच्च प्राथमिकता रखने के लिए सेवा को मजबूर कर रहा है।

सेवा को बदलने के लिए ताकि इसे अलग से मार दिया जा सके और यह मानते हुए कि यह ऑनस्टार्ट कमांड के उपयोग के कारण बाध्य सेवा के बजाय एक प्रारंभिक सेवा है, उस सेवा के लिए मैनिफेस्ट में एक प्रक्रिया नाम निर्दिष्ट करें।

प्रक्रिया और धागे डेवलपर गाइड से :

प्रत्येक प्रकार के घटक तत्व के लिए मैनिफेस्ट एंट्री- <activity>, <service>, <receiver>, and <provider> - एक एंड्रॉइड का समर्थन करता है: प्रक्रिया विशेषता जो उस प्रक्रिया को निर्दिष्ट कर सकती है जिसमें उस घटक को चलाना चाहिए। आप इस विशेषता को सेट कर सकते हैं ताकि प्रत्येक घटक अपनी प्रक्रिया में चलता है या ताकि कुछ घटक एक प्रक्रिया साझा करते हैं जबकि अन्य नहीं करते हैं। आप एंड्रॉइड भी सेट कर सकते हैं: प्रक्रिया ताकि विभिन्न अनुप्रयोगों के घटक एक ही प्रक्रिया में चल सकें-बशर्ते कि एप्लिकेशन समान लिनक्स उपयोगकर्ता आईडी साझा करें और उसी प्रमाणपत्र के साथ हस्ताक्षरित हों।

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

<service> Service <service> मेनिफेस्ट फ़ाइल में से :

एंड्रॉयड: प्रक्रिया

उस प्रक्रिया का नाम जहां सेवा चलाना है। आम तौर पर, आवेदन के लिए बनाई गई डिफ़ॉल्ट प्रक्रिया में चलाए गए एप्लिकेशन के सभी घटक। यह एप्लिकेशन पैकेज के समान नाम है। तत्व की प्रक्रिया विशेषता सभी घटकों के लिए एक अलग डिफ़ॉल्ट सेट कर सकती है। लेकिन घटक डिफ़ॉल्ट रूप से अपनी प्रक्रिया विशेषता के साथ ओवरराइड कर सकता है, जिससे आप अपने आवेदन को कई प्रक्रियाओं में फैलाने की अनुमति देते हैं।

यदि इस विशेषता को सौंपा गया नाम एक कोलन (':') से शुरू होता है, तो एक नई प्रक्रिया, एप्लिकेशन के लिए निजी, जब आवश्यक हो तब बनाई जाती है और सेवा उस प्रक्रिया में चलती है। यदि प्रक्रिया का नाम लोअरकेस चरित्र से शुरू होता है, तो सेवा उस नाम की वैश्विक प्रक्रिया में चली जाएगी, बशर्ते कि उसे ऐसा करने की अनुमति हो। यह संसाधनों के उपयोग को कम करने, प्रक्रियाओं को साझा करने के लिए विभिन्न अनुप्रयोगों में घटकों को अनुमति देता है।

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

मैं एक ऐसा एप्लीकेशन विकसित कर रहा हूं जिसमें सेंसर डेटा एकत्र करने के लिए पृष्ठभूमि सेवा बनाई गई हो। मैं अपनी गतिविधि से सेवा शुरू कर रहा हूं:

startService(new Intent(this, MyService.class));

मैंने सेवा बनाई है ताकि एप्लिकेशन नष्ट हो जाए, पृष्ठभूमि सेवा अभी भी डेटा एकत्र करना जारी रखती है। मैंने कोशिश की, और यह एक निश्चित हद तक काम किया। मेरी समस्या यह है कि जब मैं एप्लिकेशन को मारता हूं, तो सेवा फिर से शुरू होती है क्योंकि onStart() सेवा और onStart() विधियों को लागू किया जाता है। क्या कोई तरीका है जिसके साथ सेवा को पुनरारंभ नहीं किया गया है?

अद्यतन करें:

जैसा कि नीचे दिए गए उत्तर में सुझाया गया है, मैंने सेवा में निम्न विधि जोड़ा लेकिन कोई भाग्य नहीं।

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}

चिपचिपा शुरू न करें किटकैट से ऊपर काम नहीं करता है, और दूसरा ऑन टास्क ने मार्शमोलो के ऊपर काम नहीं किया है। onTaskRemoved कुछ अपवादों को संभालने के द्वारा इस्तेमाल किया जा सकता है। उस पर काम नहीं किया। लेकिन उसको आजमाएं।


मुझे इस सवाल का जवाब देने में बहुत देर हो चुकी है, लेकिन हो सकता है कि यह दूसरों के लिए सहायक हो। यह वास्तव में मेरे संगीत प्लेयर ऐप के लिए मेरी मदद की।

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

startForeground(int Notification_id,Notification);

यह आपकी सेवाओं को पुन: प्रारंभ किए बिना और इसके तरीकों को फिर से शुरू किए बिना पृष्ठभूमि में चलाएगा

documentation


मैं एक ही समस्या में भाग गया और सेवा को वैश्विक प्रक्रिया में चलाने के द्वारा इसे हल करने में सक्षम था। आप इसे मेनिफेस्ट टैग में जोड़कर ऐसा करते हैं:

प्रक्रिया = "com.myapp.ProcessName"

(जो भी नाम बनाओ।)

जब मैंने ऐसा किया तो मुझे पता चला कि ऐप को सूची से हटा दिया गया है जब मेरी सेवा नहीं मारा गया था (और पुनरारंभ)। संभवतः ऐसा इसलिए है क्योंकि जब आप इसे स्वाइप करते हैं तो ऐप प्रक्रिया मारे जाती है, लेकिन वैश्विक सेवा प्रक्रियाएं नहीं होती हैं।

इसका नुकसान यह है कि आपके ऐप और सेवा के बीच संचार अब आईबींडर इंटरफ़ेस के माध्यम से होना चाहिए; आप सीधे किसी अन्य एप्लिकेशन या सेवा में फ़ंक्शंस को कॉल नहीं कर सकते हैं, क्योंकि वे विभिन्न प्रक्रियाओं में चल रहे हैं।


यह स्टार्ट कमांड पर लौटाए गए मान पर निर्भर करता है।

आपको START_NOT_STICKY वापस करना होगा

documentation अनुसार:

प्रारंभिक सेवाओं के लिए, ऑपरेशन के दो अतिरिक्त प्रमुख तरीके हैं, वे स्टार्ट कमांड () से लौटने वाले मूल्य के आधार पर चलाने के लिए निर्णय ले सकते हैं: START_STICKY उन सेवाओं के लिए उपयोग किया जाता है जो स्पष्ट रूप से प्रारंभ और बंद किए गए हैं, जबकि START_NOT_STICKY या START_REDELIVER_INTENT का उपयोग किया जाता है उन सेवाओं के लिए जो उन्हें भेजे गए किसी भी आदेश को संसाधित करते समय केवल चलना चाहिए

संक्षेप में: यदि आप संसाधनों के उपलब्ध होने पर START_STICKY सेवा को पुनर्निर्मित करते हैं तो वापस लौटते हैं। यदि आप START_NOT_STICK वापस लौटते हैं तो आपको एक नया इरादा भेजने वाली सेवा को फिर से सक्रिय करना होगा।

चूंकि इस सब ने मेरी जिज्ञासा को ट्रिगर किया, इसलिए मैंने इसका परीक्षण करने के लिए नमूना ऐप बनाया। आप यहां सभी स्रोतों के साथ ज़िप पा सकते हैं। एक स्टार्ट सर्विस बटन और एक स्टॉप सेवा बटन है जो आप उनसे अपेक्षा करते हैं। सेवा ऑनस्टार्ट कमांड में START_NOT_STICKY लौटाती है। मैंने टोस्ट, ऑनस्टार्ट कमांड और ऑनस्ट्रोय में टोस्ट्स लगाए।

यहां क्या होता है:

  • अगर मैं स्टार्ट दबाता हूं, तो क्रेट और ऑनस्टार्ट को कॉल किया जाता है
  • अगर मैं स्टॉप दबाता हूं, तो डस्ट्रॉय ट्रिगर होता है
  • अगर मैं दो बार शुरू करता हूं, तो क्रेट को एक बार और स्टार्ट कमांड दो बार बुलाया जाता है

तो यह व्यवहार करता है जैसा कि एक उम्मीद करेगा।

यदि मैंने सेवा शुरू की है और ऐप को मार डाला है जैसा आपने वर्णन किया है, तो डेस्ट्रॉय को कॉल नहीं किया जाता है, लेकिन न तो क्रेट या ऑनस्टार्ट पर।

अगर मैं ऐप पर वापस आ जाता हूं और मैं फिर से शुरू करता हूं, तो क्रेट को कॉल किया जाता है जिसका अर्थ है कि, जैसा कि मैंने पहले लिखा था, START_NOT_STICKY सेवा को स्वचालित रूप से पुनरारंभ करने से रोकता है।

मुझे लगता है कि आपके ऐप में कुछ और है जो सेवा को फिर से शुरू करता है (शायद एक लंबित इरादा)।







background-service