2016-05-08 8 views
11

मेरे पास एक मुख्य गतिविधि ए है जो डीबी से पूछताछ करने के लिए कर्सर लोडर का उपयोग करता है। यह मैं गतिविधि में बनाने OnCreate() विधि:कर्सर लोडर ऑनलोडर रीसेट() डिवाइस रोटेशन के बाद क्यों कहा जाता है?

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ... 
    getSupportLoaderManager().initLoader(LOADER_MEASUREMENTS, null, A.this); 
} 

गतिविधि एक भी लागू करता CursorLoader के लिए 3 कॉलबैक:

public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) 
public void onLoaderReset(Loader<Cursor> loader) 

जब मैं डिवाइस बारी बारी से, मैं सही जीवन चक्र के तरीकों को चलाने देखें:

A.onPause() 
A.onStop() 
A.onDestroy()   
A.onCreate()  <-- re-connect to existing loader, onCreateLoader() not called 
A.onLoadFinished() 
A.onStart() 
A.onResume() 

फिर मैं एक उप-गतिविधि बी खोलता हूं और अपना डिवाइस घुमाता हूं। जब मैं बी समाप्त करने और गतिविधि एक मैं निम्नलिखित रन देखने के लिए वापसी:

B.onPause() 
     A.onLoaderReset()  <- why does this run? 
     A.onDestroy()   
     A.onCreate() 
     A.onCreateLoader()  <- now runs as loader is null 
     A.onStart() 
     ... 

क्यों मेरी लोडर रीसेट, क्योंकि मैं गतिविधि बी खुला था और एक डिवाइस घुमाने किया है? बस उस गतिविधि बी को जोड़ने के लिए डीबी या कर्सर लोडर से कोई लेना देना नहीं है।

+2

[यह प्रश्न] (http://stackoverflow.com/questions/15897547/loader-unable-to-retain-itself-during-certain-configuration-change?lq=1) और संबंधित प्रश्न संबंधित हैं। हो सकता है कि आप वहां कुछ ढूंढ सकें जो मदद कर सके। –

+0

धन्यवाद जॉर्ज - वह प्रश्न बिल्कुल उसी समस्या पर चर्चा करता है जो मेरे पास है। ऐसा लगता है कि यह समर्थन लोडर प्रबंधक के कारण हो सकता है। – MickeyR

+2

यह [लिंक] (https://code.google.com/p/android/issues/detail?id=183783) कहता है कि यह v24 में तय किया जाएगा। – MickeyR

उत्तर

1

ऐसा लगता है कि LoaderManager के साथ ऐसा कुछ नहीं है और गतिविधि स्थिति को बनाए रखना नहीं है।

LoaderManagerandroid.app.FragmentHostCallback और void doLoaderStop(boolean retain) द्वारा प्रबंधित किया जाता है इस वर्ग में अंतर होता है। तर्क के आधार पर यह retain() या stop() इसके लोडर होगा।

गतिविधि ए में कॉन्फ़िगरेशन बदलते समय (आपकी स्क्रीन घुमाने) गतिविधि को नष्ट कर दिया जाता है और तुरंत पुनर्निर्मित किया जाता है। ActivityThread#handleRelaunchActivity() में mChangingConfigurations गतिविधि का मूल्य true पर सेट हो जाता है। यह महत्वपूर्ण है, क्योंकि जब विन्यास परिवर्तन पर अपनी गतिविधि को रोकने, इस Activity में बुलाया जाता है:

final void performStop() { 
    mDoReportFullyDrawn = false; 
    mFragments.doLoaderStop(mChangingConfigurations /*retain*/); 
    // ... 
} 

आप क्या होता है — अपने Android स्थापना स्रोतों और grep होना चाहिए इस — करने के लिए भयानक है में गहरी उतरते कोशिश कर सकते हैं लेकिन मैं बस बाकी का सारांश दूंगा।

अस्वीकरण: मैं अच्छी तरह से निम्नलिखित को सत्यापित नहीं किया है, लेकिन यह है कि क्या मैं समझता हूँ हो रहा है।

जैसा कि ऊपर देखा जा सकता है, जब गतिविधि फिर से लॉन्च यह बजाय लोडर उन्हें रोक रख सकेंगे के लिए फिट देखा जाता है। जब आप गतिविधि ए को घुमाते हैं, तो लोडर बनाए रखा जाता है। जब आप गतिविधि बी को घुमाते हैं, तो गतिविधि बी तुरंत पुनर्निर्मित हो जाती है, जबकि गतिविधि ए को नष्ट कर दिया जाता है। पहले के विपरीत, लोडर बंद कर दिया जाएगा।

स्टॉप किए गए लोडर को केवल लोडर मैनेजर द्वारा देखा गया फिट के रूप में नष्ट और पुनर्निर्मित किया जा सकता है, और यह आपके साथ हो रहा है।

आप एक अच्छे अपने आप को देखने के लिए ले जाना चाहते हैं, तो यह देखें:

  • app/LoaderManager या v4/app/LoaderManager
  • app/FragmentHostCallback
  • Activity और ActivityThread
1

आप बस एक के अंदर एक ब्रेकपाइंट सेट कर सकते हैं .onLoaderReset() और somethin का उपयोग कर समस्या निवारण के लिए स्टैक ट्रेस देखने के लिए डीबग मोड में ऐप चलाएं की तरह जी:

/** 
    * Stops and removes the loader with the given ID. If this loader 
    * had previously reported data to the client through 
    * {@link LoaderCallbacks#onLoadFinished(Loader, Object)}, a call 
    * will be made to {@link LoaderCallbacks#onLoaderReset(Loader)}. 
    */ 
    public abstract void destroyLoader(int id); 

ऐसा लगता है कि आप लोडर जब स्क्रीन को घुमाने (विन्यास परिवर्तन के कारण) को नष्ट कर दिया जाता है:

class A extends Activity implements LoaderManager.LoaderCallbacks 
{ 
    @Override 
    public void onLoaderReset(Loader loader) 
    { 
     try 
     { 
      // Constructs a new Exception that includes the current stack trace. 
      throw new Exception(); 
     } 
     catch (Exception e) 
     { 
      Log.d("TAG", Log.getStackTraceString(e)); 
     } 
    } 
} 
3

मैं आप इस विधि मिल जाएगा LoaderManagersource code जाँच की। लोडर मैनेजर आंतरिक रूप से नष्ट लोडर विधि को कॉल करता है जो बदले में ऑनलोडर रीसेट कॉलबैक विधि को कॉल करता है।

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