2013-03-17 3 views
7

प्रश्न:
मैं ब्लूटूथ कनेक्शन को प्रबंधित (कनेक्ट, पढ़ना, लिखना, डिस्कनेक्ट) कैसे कर सकता हूं जो कॉन्फ़िगरेशन परिवर्तनों के माध्यम से बनी रहती है?कॉन्फ़िगरेशन परिवर्तनों के माध्यम से एंड्रॉइड पर ब्लूटूथ कनेक्शन का प्रबंधन कैसे करें?

ActionBarSherlock का उपयोग कर डिवाइस संस्करण 2.2 "फियोयो" के साथ संगत समाधानों को प्राथमिकता दें।

समस्याएं ...

  • न तो BluetoothDevice है और न ही BluetoothSocketonSaveState में बनाए रखा जा सकता है।

  • keep my app responsive के लिए, 12 सेकंड अवरुद्ध कॉल BluetoothSocket.connect() को अलग थ्रेड पर बनाया जाना चाहिए। Runnable शुरू करना लंबे कार्यों को थ्रेड करने का अनुशंसित तरीका है, लेकिन यह कॉन्फ़िगरेशन परिवर्तन पर पुनर्प्राप्त करने का प्रयास करने वाला एक दुःस्वप्न है। आधिकारिक दस्तावेज़ तीन अलग-अलग समाधानों को इंगित करते हैं।

    • getLastNonConfigurationInstance() का उपयोग करें, जो बहिष्कृत (गंभीरता से ?!) है।

    • android:configChanges="keyboardHidden|orientation"BluetoothChat Sample की तरह सेट करें। हालांकि, यह सभी प्रकार के कॉन्फ़िगरेशन परिवर्तनों के लिए जिम्मेदार नहीं है।

    • & Shelves Example जैसे कार्यों को पुनरारंभ करें। इस मामले में, यह संभावित रूप से एक और 12 सेकंड बर्बाद कर सकता है।

अद्यतन 1

  • इसके अलावा अनुसंधान मुझे asyncTaskLoader के लिए नेतृत्व किया है, लेकिन ऐसा लगता है कि यह केवल पूरा होने पर यूआई अद्यतन कर सकते हैं, और अद्यतन प्रदान नहीं कर सकते लगता है।

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

अद्यतन 2

As pointed out by Reuben, Fragment.setRetainInstance(bool) पदावनत getLastNonConfigurationInstance() प्रतिस्थापित किया है। इस बिंदु पर, ऐसा लगता है कि setRetainInstance(true) का उपयोग कर लगातार गैर-यूआई खंड बनाने का सबसे अच्छा विकल्प है।

उत्तर

1

इसमें समाधान का एक समूह है। यदि आप Fragments का उपयोग नहीं कर रहे हैं तो सबसे आसान विकल्प है RetainNonConfigurationInstance() पर ओवरराइड करना है। इस बात से कोई फर्क नहीं पड़ता कि एपीआई को बहिष्कृत किया गया है, यही कारण है कि वे चाहते हैं कि आप टुकड़ों का उपयोग करें (जहां, निष्पक्ष होना, Fragment.setRetainInstance() इस पूरे मुद्दे को हमेशा ब्रेनर नहीं करता है)। यह एपीआई लंबे समय तक कहीं नहीं जायेगा।

मुझे क्या करना चाहते हैं क्या onRetainNonConfiguration() ओवरराइड 'इस', यानी एक मृत गतिविधि उदाहरण के संदर्भ में वापस जाने के लिए है, और वस्तु refs आप OnCreate (से की जरूरत पर कॉपी तो), अर्थात्:

Object obj = getLastNonConfigurationInstance(); 
if (obj != null) { 
    MyActivity deadActivity = (MyActivity)obj; 
    this.foo = deadActivity.foo; 
    this.bar = deadActivity.bar; 
    ... 
} 

वैकल्पिक रूप से आप सेवा का उपयोग कर सकते हैं, लेकिन मैं व्यक्तिगत रूप से उन्हें नापसंद करता हूं। पार-प्रक्रिया सामग्री करने के लिए उपयोगी, इसमें कोई संदेह नहीं है, लेकिन अन्यथा वे किसी समस्या की तलाश में समाधान हैं।

आखिरकार, आदेश के सामान्य बिंदु के रूप में आप सुरक्षित रूप से 'वैश्विक' डेटा को अपने एप्लिकेशन संदर्भ में सुरक्षित कर सकते हैं। ऐसा करने के लिए आप subclass android.app.Aplication और < एप्लिकेशन एंड्रॉइड का उपयोग करें: name = "MyApp" > आपके मैनिफेस्ट में विशेषता। यहां वैश्विक स्थिर डेटा में एप्लिकेशन ऑब्जेक्ट को रेफरी करना भी उपयोगी है, इसलिए AsyncTasks और अन्य संदर्भ-कम कोड किसी भी कारण से कॉन्टेक्स्ट पैरामीटर को पास किए बिना हमेशा एप्लिकेशन संदर्भ में जा सकते हैं।

class MyApp extends Application { 
... 

    public static MyApp context; 
    ... 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     context = this; 

     ... set up global data here ... 
    } 
... 
} 
+0

क्या यह इस गतिविधि के लिए एक टुकड़ा बनाने लायक है, इसलिए मैं 'setRetainInstance' का उपयोग कर सकता हूं? क्या "बनाए रखा" खंड एक अभिविन्यास परिवर्तन पर घूमने और आकार बदलने में सक्षम हो जाएगा? इसके अलावा, [इस तो सवाल] (http://stackoverflow.com/questions/4585627) मुझे सिखाया है कि आवेदन की एक उपवर्ग एक सुरक्षित तरीका वैश्विक स्टोर करने के लिए नहीं है। वास्तव में, यह उन बगों का कारण बन सकता है जो पुन: बनाना लगभग असंभव हैं। – firyice

+0

पुन। टुकड़ा, हाँ। बाद में बजाए चीजों को करने के टुकड़े के तरीके को गले लगाने के लायक है। आवेदन subclassing, किसी के उलझन में। हां कार्य स्थिति ओएस द्वारा जमे हुए हो सकती है जबकि प्रक्रिया मारे जाती है, लेकिन क्या? Application.onCreate() तब भी चलता है जब प्रक्रिया/कार्य पुनरारंभ/फिर से शुरू होता है। –

+0

तो क्या? यदि प्रक्रिया पुनरारंभ होती है और Application.onCreate() कहा जाता है, तो आपने उन वैश्विक चरों में डेटा खो दिया है। एकमात्र तरीका जो ठीक हो सकता है स्थिरांक के लिए है। – firyice

8

मैं एक Service कि अपने ब्लूटूथ कनेक्शन संभाल हैं का उपयोग करके इस समस्या का समाधान होगा, और वापस अपनी गतिविधि को फिर this answer.

में वर्णित के रूप कि सेवा बात करते हैं तो आप ASyncTask इस्तेमाल कर सकते हैं बस दिखाने/छिपाने एक संवाद, और रोटेशन पर ASyncTasks को रद्द/पुनरारंभ करें, जैसा कि आपने उल्लेख किया है Shelves Example द्वारा किया जाता है।

सेवाएं वास्तव में उस भयानक नहीं हैं और आपकी समस्या के लिए सबसे अच्छा उपकरण हो सकता है।

+0

यह एक सुरक्षित समाधान की तरह लगता है। हालांकि, यह मुझे जैकहमेर के साथ एक नाखून में ड्राइविंग के बराबर के रूप में भी मारता है। सेवाएं वास्तव में प्रतीत होती हैं कि वे कई प्रक्रियाओं के साथ संवाद करने के लिए हैं। हां, इन्हें किसी प्रक्रिया के भीतर कुछ सरल कार्यों के लिए उपयोग किया जा सकता है, लेकिन यह अपेक्षाकृत सरल होने के लिए बहुत अधिक भारी उठाने जैसा लगता है। – firyice

+4

मैं असहमत हूं। मैं चाहता था कि मेरा एप्लिकेशन सर्वर पर पृष्ठभूमि बैकअप को संभालने के लिए चाहता है - एक साधारण 20-लाइन IntentService मुझे ढूंढने का सबसे आसान समाधान था। – Axarydax

2

आप singleton pattern के साथ प्रयास कर सकते हैं जो सब कुछ संभाल सकता है और जब आवश्यक हो तो मुख्य गतिविधि को कॉल कर सकता है।

तो यह MySingleton ऑब्जेक्ट का उदाहरण प्राप्त करने के लिए एक स्थिर विधि है, हर बार जब आप कॉल करते हैं तो वही इंस्टेंस। आप इसमें सभी ब्लूटूथ ऑब्जेक्ट्स "स्टोर" कर सकते हैं, यह प्रत्येक गतिविधि से नष्ट नहीं होगा और सुलभ नहीं होगा।

public class MySingleton { 
    private static MySingleton instance; 
    public static MySingleton getInstance() { 
     if (null == instance) { 
      instance = new MySingleton(); 
     } 
    return instance; 
} 

    private MySingleton() { 
    } 
} 
+0

यह मेरी समझ है कि आवेदन वर्ग है, जो हर अनुप्रयोग के लिए एंड्रॉयड द्वारा प्रदान की एक सिंगलटन है, अपने स्वयं के जीवन चक्र है। यह भी, दुर्लभ मामलों में, पूरे ऐप को नष्ट किए बिना नष्ट किया जा सकता है। क्या आपका मतलब एक अलग सिंगलटन वर्ग है? क्या आप यहां के बारे में बात कर रहे एक कोड उदाहरण प्रदान कर सकते हैं? – firyice

+0

मैंने वास्तव में ब्लूटूथ कनेक्शन के लिए कोशिश नहीं की, लेकिन एक सिंगलटन वर्ग को नष्ट नहीं किया जाना चाहिए। प्रारूपण के लिए क्षमा करें, मैं इतना निर्यात नहीं कर रहा हूँ, लेकिन यह सिर्फ एक नियमित रूप से सिंगलटन वर्ग है जिसमें आप ब्लूटूथ कनेक्शन से संबंधित सब कुछ होता है। ' सार्वजनिक वर्ग सिंगलटन { निजी स्थिर सिंगलटन उदाहरण; publicstatic सिंगलटन getInstance() { अगर (शून्य == उदाहरण) { उदाहरण = नए सिंगलटन(); } वापसी उदाहरण; } निजी सिंगलटन() {} } ' –

+0

स्पष्टीकरण के लिए धन्यवाद! क्या आप कोड के साथ अपना उत्तर अपडेट कर सकते हैं। कोड के रूप में स्वरूपित करने के लिए आप 4 रिक्त स्थान के साथ प्रत्येक पंक्ति को इंडेंट कर सकते हैं। – firyice

4

विजुअल/यूआई घटकों में ऐप मॉडल (तर्क या डेटा) कभी न रखें। जैसा कि आप देखते हैं, वे आते हैं और जाते हैं, और बदलते हैं।

  • आवेदन वर्ग:

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

उदाहरण:

public class App extends Application { 

    private static Beer sBeer; 

    public static void brbHoldMyBeer(Beer b){ 
    sBeer = b; 
    } 

    public static Beer imBackWheresMyBeer(){ 
    return sBeer; 
    } 

} 

इसके अलावा, आवेदन कक्षा में एक स्थिर धागा निर्वाहक सेवा हो रही है, में चल रहे कार्यों को बनाए रखने में मदद मिलेगी।

  • एक चल पृष्ठभूमि सेवा। कौन सी गतिविधियां, टुकड़े आदि बाध्य/अनबाइंड कर सकते हैं, और कमांड/अनुरोध पोस्ट कर सकते हैं। ऐप चौड़ी चल रही प्रक्रियाओं और डेटा के लिए यह अनुशंसित जगह है।

  • setRetainInstance(true) के साथ एक गैर दृश्य खंडन। यहां पर गैर दृश्य का अर्थ है कि यह एक डमी टुकड़ा है जो गतिविधि से जुड़ा हुआ है लेकिन कोई दृश्य नहीं दिखाता है। यह सिर्फ एक गतिविधि के लिए एक बनाए रखने योग्य सक्षम धारक के रूप में प्रयोग किया जाता है। गतिविधि की विस्तृत प्रक्रियाओं और डेटा के लिए यह अनुशंसा की जाती है।

+0

पेय = imBackWheresMyBeer(); – Luis

+0

[एंड्रॉइड प्रलेखन एक गैर-परिष्करण खंड में संलग्न करके विन्यास परिवर्तन के दौरान वस्तुओं को बनाए रखने का सुझाव देता है।] (Http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject) (बस पिलिंग संदर्भों पर।) –

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

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