2011-07-20 14 views
14

मेरे पास कुछ सूची फ़्रेगमेंट हैं जो अपनी सामग्री को पुनर्प्राप्त करने के लिए कर्सर लोडर का उपयोग करते हैं। चूंकि उपयोगकर्ता सामग्री के माध्यम से नीचे ड्रिल करता है, एक टुकड़ा एक दूसरे को बदल देता है (गतिविधि वही रहती है)। लेकिन अगर एक गैर सर्वोच्च टुकड़ा पर सामग्री में परिवर्तन ऐप्लिकेशन क्रैश:एंड्रॉइड: गैर-शीर्षतम टुकड़े पर कर्सर लोडर क्रैश

E/AndroidRuntime(18830): FATAL EXCEPTION: main 
E/AndroidRuntime(18830): java.lang.RuntimeException: Unable to resume activity {com.example.ExampleApp/com.example.ExampleApp.ExampleActivity}: java.lang.IllegalStateException: Content view not yet created 
E/AndroidRuntime(18830):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2120) 
E/AndroidRuntime(18830):  at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135) 
E/AndroidRuntime(18830):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:957) 
E/AndroidRuntime(18830):  at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime(18830):  at android.os.Looper.loop(Looper.java:130) 
E/AndroidRuntime(18830):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
E/AndroidRuntime(18830):  at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(18830):  at java.lang.reflect.Method.invoke(Method.java:507) 
E/AndroidRuntime(18830):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
E/AndroidRuntime(18830):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
E/AndroidRuntime(18830):  at dalvik.system.NativeStart.main(Native Method) 
E/AndroidRuntime(18830): Caused by: java.lang.IllegalStateException: Content view not yet created 
E/AndroidRuntime(18830):  at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328) 
E/AndroidRuntime(18830):  at android.support.v4.app.ListFragment.setListShown(ListFragment.java:280) 
E/AndroidRuntime(18830):  at android.support.v4.app.ListFragment.setListShownNoAnimation(ListFragment.java:266) 
E/AndroidRuntime(18830):  at com.example.ExampleApp.FirstListFragment.onLoadFinished(FirstListFragment.java:102) 
E/AndroidRuntime(18830):  at com.example.ExampleApp.FristListFragment.onLoadFinished(FirstListFragment.java:20) 
E/AndroidRuntime(18830):  at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:414) 
E/AndroidRuntime(18830):  at android.support.v4.app.LoaderManagerImpl$LoaderInfo.reportStart(LoaderManager.java:298) 
E/AndroidRuntime(18830):  at android.support.v4.app.LoaderManagerImpl.doReportStart(LoaderManager.java:751) 
E/AndroidRuntime(18830):  at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:512) 
E/AndroidRuntime(18830):  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) 
E/AndroidRuntime(18830):  at android.app.Activity.performStart(Activity.java:3791) 
E/AndroidRuntime(18830):  at android.app.Activity.performRestart(Activity.java:3821) 
E/AndroidRuntime(18830):  at android.app.Activity.performResume(Activity.java:3826) 
E/AndroidRuntime(18830):  at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110) 
E/AndroidRuntime(18830):  ... 10 more 

यह जब एक पृष्ठभूमि अद्यतन सामग्री बदलता है, या हो सकता है जब होम स्क्रीन से उपयोगकर्ता रिटर्न और एक अन्य टुकड़ा शीर्ष पर है बैक स्टैक का। onLoadFinished हैंडलर UI को अपडेट करने का प्रयास करता है, जो अब मौजूद नहीं है। लेकिन खंड अभी भी कर्सर अपडेट क्यों प्राप्त कर रहा है?

अगर टुकड़ा दिखाई नहीं देता है तो मैंने अपडेट को निरस्त कर काम किया है, लेकिन यह गलत काम करने जैसा लगता है।

यहाँ क्या मेरी टुकड़ा लग रहा है, जैसे संक्षिप्तता के लिए एक छोटे से संपादित है:

public class FirstListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { 
    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     // Initialize empty cursor adapter. 
     mAdapter = new ExampleCursorAdapter(getActivity(), null, 0); 
     setListAdapter(mAdapter); 

     // Start with a progress indicator 
     setListShown(false); 

     // Prepare the loader. Either re-connect with an existing one, or start a new one. 
     getLoaderManager().initLoader(EXAMPLE_LOADER_ID, null, this); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     return new CursorLoader(getActivity(), ExampleProvider.CONTENT_URI, PROJECTION, null, null, null); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     // Do nothing if we're not visible. 
     if(!isVisible()) { 
      return; 
     } 

     // Swap the new cursor in. (The framework will take care of closing the 
     // old cursor once we return.) 
     mAdapter.swapCursor(data); 

     // The list should now be shown. 
     if(isResumed()) { 
      setListShown(true); 
     } else { 
      setListShownNoAnimation(true); 
     } 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     // This is called when the last Cursor provided to onLoadFinished() above is about to be 
     // closed. We need to make sure we are no longer using it. 
     mAdapter.swapCursor(null); 
    } 
} 

isVisible() जाँच दुर्घटना से बचाता है, लेकिन यह उदाहरण कोड मैंने देखा है में से किसी में नहीं है। यहाँ क्या गलत है?


संपादित करें: पर्याप्त बेशक, मैं एक पुराने एक बंद कर्सर का उपयोग करने की कोशिश कर दृश्य के साथ एक StaleDataException साथ समापन। तो जब दृश्य नष्ट हो जाता है तो अब मैं लोडरमेनर को नष्ट कर रहा हूं। अभी भी यह सुनिश्चित नहीं है कि यह सही काम है, और मैं StaleDataException को पुन: उत्पन्न नहीं कर सकता।

मैं ऊपर से isVisible() हैक हटा दिया और कहा कि इस:

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

    // The CursorLoader example doesn't do this, but if we get an update while the UI is 
    // destroyed, it will crash. Why is this necessary? 
    getLoaderManager().destroyLoader(EXAMPLE_LOADER_ID); 
} 

उत्तर

2

इस सूची में टुकड़े सूची दृश्य हो रही के साथ एक समस्या हो रहा है। कुछ कारणों से getListView() एक वैध दृश्य वापस नहीं करेगा जब तक कि टुकड़ा दिखाई नहीं दे रहा है। मैंने इसे स्टार्ट() से पहले जीवन चक्र में किसी भी चीज़ पर अवैध राज्य अपवाद फेंक दिया है।

जिस तरह से मैं समस्या हल करता हूं, मैं लोडर को ऑनक्रेट व्यू() विधि में कॉल करता हूं। जब लोडर डेटा के साथ लौटाता है तो मैं यह देखने के लिए जांच करता हूं कि गतिविधि शुरू हो गई है या नहीं। यदि ऐसा है तो मैं इसे सूची दृश्य में लोड करता हूं, अगर मैं इसे स्थानीय चर में संग्रहीत नहीं करता हूं, और फिर ऑनस्टार्ट() विधि में डेटा लोड करता हूं।

यह एक सुपर हैक की तरह लगता है, लेकिन यह काम करता है।

+0

हाँ लोडर के साथ बहुत जल्द लौटने के साथ कुछ बग लगता है और निष्क्रियता() अभी भी शून्य है (टुकड़ा पूरी तरह से जुड़ा हुआ नहीं है)। लोडर कभी-कभी फ्रेमवर्क द्वारा पुनरारंभ किया जाता प्रतीत होता है। जो इसे बहुत जल्दी लौटने का कारण बनता है। – pjco

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