16

मेरा ऐप Service पर निर्भर करता है जो पृष्ठभूमि में बाहरी हार्डवेयर के साथ सिंक में रहता है। चूंकि सेवा मुख्य थ्रेड पर चलती है, इसलिए यह किसी इंटेंट सेवा का उपयोग करके असीमित रूप से कोई भी भारी कार्य करता है।एंड्रॉइड सर्विस इंटेंट सेवा के लिए परिणाम रिसीवर बढ़ाती है, CREATOR को कैसे कार्यान्वित करें?

public class MyService extends Service { 
    private final Handler handler = new Handler(); 

    void someMethodDoesCallBarAsynchronously(){ 
    Intent i = new Intent(this, MyIntentService.class); 
    i.putAction(ACTION_FOO); 
    i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(handler)); 
    startService(toGetScannerStatus); 
    } 

    void receivedFooResult(String bar){ 
    //... 
    } 

    public class MyResultReceiver extends ResultReceiver{ 

    public MyResultReceiver(Handler handler){ 
     super(handler); 
    } 

    @Override 
    protected void onReceiveResult(int resultCode, Bundle resultData) { 
     super.onReceiveResult(resultCode, resultData); 

     switch(resultCode){ 
     case RESULT_CODE_FOO: 
      receivedFooResult(resultData.getString(FOO_RESULT)); 
     break; 
     } 
    } 
    } 
} 

public class MyIntentService extends IntentService { 

    public MyIntentService(){super("MyIntentService");} 

    @Override 
    protected void onHandleIntent(Intent intent) { 
    switch (intent.getAction()) { 
     case ACTION_FOO: 
     ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER); 
     Bundle bundle = new Bundle() 
     bundle.putString(FOO_RESULT, foo()); 
     receiver.send(RESULT_CODE_FOO, b); 
     break; 
    } 
} 

अब, आधे साल है और कुछ अपडेट के बाद, एंड्रॉयड स्टूडियो शिकायत है कि MyResultReceiverलागू करता Parcelable लेकिन एक निर्माता क्षेत्र प्रदान नहीं करता है: यहाँ कोड का एक minimalized उदाहरण नियंत्रण प्रवाह की व्याख्या करने के लिए है। समस्या एक, MyResultReceiver एक आंतरिक वर्ग है, इसलिए मुझे इसे अपनी कक्षा में रखना है। मैं इसे static नहीं बना सकता क्योंकि इसमें MyService का संदर्भ होना चाहिए। यह अभी भी काफी आसान है:

public class MyService extends Service { 
    private final Handler handler = new Handler(); 

    void someMethodDoesCallBarAsynchronously(){ 
    Intent i = new Intent(this, MyIntentService.class); 
    i.putAction(ACTION_FOO); 
    i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(this, handler)); 
    startService(toGetScannerStatus); 
    } 

    void receivedFooResult(String bar){ 
    //... 
    } 
} 

public class MyResultReceiver extends ResultReceiver{ 
    private final MyService myService; 

    public MyResultReceiver(MyService s, Handler handler){ 
    super(handler); 
    this.myService = myService; 
    } 

    @Override 
    protected void onReceiveResult(int resultCode, Bundle resultData) { 
    super.onReceiveResult(resultCode, resultData); 

    switch(resultCode){ 
     case RESULT_CODE_FOO: 
     myService.receivedFooResult(resultData.getString(FOO_RESULT)); 
     break; 
    } 
    } 
} 

अब मैं एक सार्वजनिक स्थैतिक क्षेत्र जोड़ सकता हूं। लेकिन CREATOR को सही तरीके से कैसे कार्यान्वित करें?

public class MyResultReceiver extends ResultReceiver { 

    public static final Parcelable.Creator<MyResultReceiver> CREATOR 
    = new Parcelable.Creator<MyResultReceiver>() { 
     public MyResultReceiver[] newArray(int size) { 
      return new MyResultReceiver[size]; 
     } 
     public MyResultReceiver createFromParcel(Parcel in) { 
      // ??? 
     } 
     }; 

आप करना चाहते हैं: यह क्यों ज़रूरी है? इसके लिए क्या उपयोग किया जाएगा? जब यह आपकी समस्या की बात आती है, तो आप आसानी कि एक Service में, लेकिन यह आप पर निर्भर है कर सकता है::

+0

क्यों? आपको 'MyIntentService' के लिए क्या चाहिए? 'MyService' के अंदर 'हैंडलर थ्रेड' में 'भारी कार्य' क्यों न करें? 'परिणाम रिसीवर', 'CREATOR' आदि के लिए कोई ज़रूरत नहीं है (यदि आप' IntentService 'में एक नज़र डालेंगे तो आप देखेंगे कि इसमें' हैंडलर थ्रेड 'के अलावा कुछ भी नहीं है) – pskink

+0

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

+0

'@SuppressLint ("पार्सलक्रिएटर") कक्षा का प्रयास करें MyResultReceiver परिणाम रिसीवर {... 'को गंभीरता से सरल वास्तुकला (दो सेवाओं के बिना) पर विचार करें – pskink

उत्तर

29

अपने वर्तमान वास्तुकला बहुत जटिल imho है आप क्या मिला एक है के रूप में किसी भी CREATOR बनाने की जरूरत नहीं है लिंट चेतावनी, बस इस तरह SuppressLint एनोटेशन जोड़ें:

@SuppressLint("ParcelCreator") 
public class MyResultReceiver extends ResultReceiver { 
+0

मीठे, धन्यवाद !! – mur7ay

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