2013-05-22 9 views
9

मेरे पास एक बाध्य सेवा है। एक गतिविधि इसे बाध्यकारी है। यह गतिविधि की onStop() विधि पर सेवा को अनबिंड करता है।गतिविधि के रनटाइम में परिवर्तन होने पर बाध्य सेवा को नष्ट होने से कैसे रोकें (उदा: अभिविन्यास)

समस्या यह है कि यदि रनटाइम में परिवर्तन होता है (उदाहरण के लिए, अभिविन्यास परिवर्तन) गतिविधि के साथ होता है, तो गतिविधि को फिर से बनाया जाता है। इसलिए, गतिविधि से onStop() विधि को कॉल किया जाता है, और गतिविधि उस विधि में सेवा को अनबिंड करती है, जिसके परिणामस्वरूप सेवा का विनाश होता है (और इसे पुनरारंभ करना)।

मैं गतिविधि को अदृश्य होने पर सेवा रोकते समय रनटाइम परिवर्तनों में नष्ट होने से सेवा को संरक्षित करना चाहता हूं। आप कह सकते हैं कि startService() आज़माएं लेकिन यह गतिविधि को अदृश्य होने पर सेवा को रोकना नहीं बनाता है। अगर मैं स्टॉप सेवा गतिविधि onStop() जोड़ता हूं, तो परिणाम bindService() और unbindService() जैसा ही होता है।

पोस्टडिलेइंग unbindService() एसिटीविटी के onStop() में इस समस्या को आंशिक रूप से हल कर सकते हैं, लेकिन देरी का समय मनमाने ढंग से होगा, और यह गतिविधि को कुछ समय के लिए जीसी प्राप्त करने से रोकता है। मुझे एक और स्पष्ट समाधान चाहिए।

मुझे android:configChanges="orientation" जैसे समाधान नहीं चाहिए क्योंकि अन्य रनटाइम परिवर्तन भी हैं, और यह रनटाइम परिवर्तनों को संसाधित करने का एक निराश तरीका है।

संक्षेप में, मैं चाहता हूं कि सेवा एक टुकड़े की तरह कार्य करे जो setRetainInstance(true) कहलाती है। हालांकि, टुकड़ों में bindService() की तरह कुछ नहीं है। मुझे क्या करना चाहिए?

उत्तर

9

हालांकि, टुकड़ों में bindService() जैसी कोई चीज़ नहीं है।

लेकिन वे Application संदर्भ से bindService() उपयोग कर सकते हैं:

public class BshFragment extends Fragment implements OnClickListener, 
    ServiceConnection { 
    private IScript service=null; 
    private Button btn=null; 

    public View onCreateView(LayoutInflater inflater, 
          ViewGroup container, 
          Bundle savedInstanceState) { 
    View result=inflater.inflate(R.layout.main, container, false); 

    btn=(Button)result.findViewById(R.id.eval); 
    btn.setOnClickListener(this); 
    btn.setEnabled(false); 

    setRetainInstance(true); 

    return(result); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    getActivity().getApplicationContext() 
       .bindService(new Intent(getActivity(), 
             BshService.class), this, 
           Context.BIND_AUTO_CREATE); 
    } 

    @Override 
    public void onDestroy() { 
    getActivity().getApplicationContext().unbindService(this); 
    disconnect(); 

    super.onDestroy(); 
    } 

    @Override 
    public void onClick(View view) { 
    EditText script=(EditText)getView().findViewById(R.id.script); 
    String src=script.getText().toString(); 

    service.executeScript(src); 
    } 

    @Override 
    public void onServiceConnected(ComponentName className, IBinder binder) { 
    service=(IScript)binder; 
    btn.setEnabled(true); 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName className) { 
    disconnect(); 
    } 

    private void disconnect() { 
    service=null; 
    btn.setEnabled(false); 
    } 
} 

(के रूप में this sample project में देखा, this book में शामिल)

Application संदर्भ का उपयोग करके, हम एक ही उपयोग कर सकते हैं बाइंडिंग और अनबाइंडिंग के लिए Context। टुकड़े को बनाए रखने से, हम कॉन्फ़िगरेशन परिवर्तन पर असंतुलन और पुन: बाध्यता से बच सकते हैं।

व्यक्तिगत रूप से, मैं बस बाध्यकारी पैटर्न से बचने की कोशिश करता हूं। मैं ढीले-युग्मित इंटरफेस का प्रशंसक हूं, और इसलिए मैं कमांड पैटर्न और startService() के माध्यम से सेवाओं का उपयोग करना पसंद करता हूं। onCreate में

+0

मैं एप्लिकेशन संदर्भ के साथ नहीं आया था। जवाब के लिए धन्यवाद। – Naetmul

2

कॉल startService और फिर onStop

@Override 
protected void onStop() 
{ 
    super.onStop(); 
    if (!isChangingConfigurations()) 
    { 
      // call stopService 
    } 
} 
+0

यह इसके कनेक्शन को रिसाव करने के लिए एक बाध्य सेवा का कारण बन जाएगा। – Adam

0

क्रम परिवर्तन के दौरान जिंदा एक ही बाध्य सेवा रखने के लिए सेवा वर्ग में keepAlive की तरह एक विधि को परिभाषित करने से हो सकता है एक और तरीका है:

public void keepAlive(boolean value) { 
    if (value) startService(new Intent(getApplicationContext(), getClass())); 
    else stopSelf(); 
} 

@Override 
public void onRebind(Intent intent) { 
    keepAlive(false); 
} 

@Override 
public boolean onUnbind(Intent intent) { 
    return true; 
} 

onRebind() में केवल-बाध्य सेवा स्थिति को रीसेट किया गया है।

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