2015-12-14 10 views
5

मेरा ऐप अनिवार्य रूप से एक पृष्ठभूमि सेवा कभी कभी मुख्य द्वारा चलाए जा रहे एक सॉकेट सर्वर की खोज सक्षम बनाने के उद्देश्य के लिए एक NSD सेवा (Bonjour सेवा) रजिस्टर करने की जरूरत है पृष्ठभूमि सेवा (ऐप द्वारा संचालित उर्फ)।एंड्रॉयड: एक Bonjour सेवा को रोकने से के बाद माता-पिता की प्रक्रिया से बाहर निकलने के चलते रहने दिया abrubtly

अगर मैं सही ढंग से Android Bonjour Service doc पढ़ रहा हूँ, यह कैसे आप Bonjour सेवा (संक्षिप्तता के लिए संक्षिप्त) शुरू होता है:

mNsdManager = Context.getSystemService(Context.NSD_SERVICE); 
mDiscoveryListener = new NsdManager.DiscoveryListener() 
mNsdManager.discoverServices(
     SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); 

... और यह कैसे आप इसे रोकना है:

mNsdManager.unregisterService(mRegistrationListener); 

यहां भाग मैं अपने सिर को चारों ओर लपेट नहीं सकता: यदि मुख्य सेवा अचानक नीचे जाती है, तो Bonjour सेवा जो दुर्घटना के समय पंजीकृत थी, तब भी चल रही है, भले ही इसका कोई उद्देश्य न हो (सॉकेट सर्वर यह डिस्को में मदद करता है ver अब चारों ओर नहीं है)।

मैं मुख्य सेवा को पुनरारंभ करते समय ज़ोंबी Bonjour सेवाओं को साफ़ नहीं कर सकता क्योंकि mRegistrationListener सेवा प्रारंभ में पंजीकृत थी, अब भी आसपास नहीं है।

मुझे संदेह है कि मैं गलत दृष्टिकोण ले रहा हूं: मैं कैसे सुनिश्चित करूं कि मैं मुख्य सेवा दुर्घटनाग्रस्त होने के बाद ज़ोंबी Bonjour सेवाओं की गड़बड़ी नहीं छोड़ूं?

उत्तर

1

एंड्रॉयड Bonjour को गैर विशिष्ट, आप अपनी सेवा की स्थापना के रूप में इस सवाल का जवाब यहाँ में उल्लिखित है द्वारा दुर्घटना संभाल करने की कोशिश कर सकते: Can I call a method before my application go to crash

आप unregisterService कॉल करने के लिए इस सेट नहीं कर सकती है, आप इसे ActivityManager के API killBackgroundProcesses का उपयोग करने के लिए सेट अप करने में सक्षम होना चाहिए। यह आपके प्रकट करने की अनुमति जोड़ने की आवश्यकता है:

android.permission.KILL_BACKGROUND_PROCESSES 
+0

धन्यवाद, 'UncaughtExceptionHandler' के साथ बेजोड़ अपवादों को पकड़ना संभवतः जाने का तरीका है - हालांकि मैं मुख्य प्रक्रिया के भीतर बोनजोर सेवा चलाने का कोई तरीका ढूंढ रहा था (मुझे आश्चर्य है कि एंड्रॉइड कार्यान्वयन उस विकल्प की अनुमति नहीं देता है) । यदि अगले कुछ दिनों में कुछ भी बेहतर नहीं होता है तो मैं आपका जवाब स्वीकार करूंगा। – Hugo

+0

मैं सहमत हूं, आपको लगता है कि इसे संभालने का एक उचित तरीका है। मुझे सिद्धांत का समर्थन करने के लिए कोई दस्तावेज नहीं मिला, लेकिन यह ओएस द्वारा संभाला जा सकता है। हो सकता है कि Google सोचता है कि लोग ऐसा करने के बारे में सोच नहीं सकते हैं, इसलिए उन्हें स्वचालित रूप से इसे संभालना चाहिए! –

+0

धन्यवाद @ थ्रिल, मेरे लिए काम की गई सेवा को अनधिकृत करने के लिए 'UncaughtExceptionHandler' का उपयोग करके (मैंने सेवा के पंजीकरण के कुछ सेकंड बाद सेवा को क्रैश करके सफलतापूर्वक परीक्षण किया, एक अलग धागे में चल रहे डेमॉन टाइमर का उपयोग करके) – Hugo

2

अगर मैं तुम्हें सही ढंग से मुख्य सेवा (सर्वर सॉकेट के साथ एक) रजिस्टरों/एक Nsd सेवा unregisters जबकि एक पृष्ठभूमि सेवा शुरू होता है/खोज Nsd सेवा बंद समझा। मुझे लगता है कि यह वही है जो आप करते हैं, इसलिए आपका "दृष्टिकोण" सही है।

समस्या के संबंध में, मुझे एंड्रॉइड Nsd पर आपका स्वागत करना चाहिए। ढांचे के साथ bugs बहुत सारे हैं (जिनमें से आप अपनी समस्या पा सकते हैं) कि Android 6.0 के रूप में अभी तक डेवलपर्स को अन्य ढांचे का उपयोग करने के लिए तय नहीं किया गया है।

क्योंकि वापस मुद्दे पर हो रही है, आप UncaughtExceptionHandler कोशिश कर सकते हैं, बस ध्यान रखें कि सभी कॉलबैक एसिंक्रोनस रूप से प्रणाली द्वारा लाया जाता है में रखने के लिए, और जब यह mRegistrationListener.onServiceUnregistered() कॉल आप NPE मिल सकता है, जैसा कि आप ने कहा, "यह है अब "" के आसपास नहीं है।

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

एक और कामकाज है जिसके साथ आप कोशिश कर सकते हैं/प्रयोग कर सकते हैं। अगर मुझे सही याद है (गलत हो सकता है), Nsd को अक्षम करने पर आवश्यक सफाई होती है।मैं adb के माध्यम से इसे करने की कोशिश:

// Disable 
adb shell service call servicediscovery 2 
// Enable 
adb shell service call servicediscovery 2 i32 1 

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

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

Nsd के साथ आगे बढ़ने से पहले, जवाब को सारांशित करते हुए, मैं आपके समय और प्रयासों को संभव बर्बाद करने से बचने के लिए इसकी कार्यक्षमता/बग के बारे में एक खोज करने की अत्यधिक अनुशंसा करता हूं। लिंक के अतिरिक्त कुछ संदर्भों ऊपर दी गई:

  1. NSD Device Lost Message Not Received on Disabling Wifi
  2. NsdManager doesn't stop service discovery

पी.एस. व्यक्तिगत रूप से, कई Nsd फ्रेमवर्क कीड़े के साथ संघर्ष करने के बाद, मैंने अपना खुद का ढांचा लिखना समाप्त कर दिया।

+0

धन्यवाद @ ओनिक 'UncaughtExceptionHandler' का उपयोग करके डिज़ाइन किए गए काम के रूप में, मैंने एक डिमन टाइमर ('टाइमर टाइमर = नया टाइमर (सत्य) का उपयोग करके, एक अलग थ्रेड से मुख्य सेवा को क्रैश करके सफलतापूर्वक परीक्षण किया; timer.schedule (नया सिमुलेट अनकॉचएक्सप्शन(), 2000);') – Hugo

+0

बहुत अच्छी @ हूगो, एक अलग धागे में 'एनएसडी' काम को संभालना एक अच्छा विचार है, - स्पष्ट रूप से आपके पास उस मामले में सेवा को अपंजीकृत करने का समय है। हालांकि, मैं अभी भी सभी 'एनएसडी' कॉलबैक की जांच करने की सलाह देता हूं, खासकर जब 'वाईफाई' ('ईथरनेट') चालू/बंद करना ... – Onik

संबंधित मुद्दे