2012-06-08 9 views
6

में एक LoaderManager से लौटे मैं एक कर्सर (LoaderManager.LoaderCallbacks से) एक onLoadFinished कॉलबैक पर लौट आए है, और मैं इस कर्सर पर कुछ (संभवतः महंगा) पोस्ट-प्रोसेसिंग करना चाहते हैं। इसलिए, मैं AsyncTask को फायर कर रहा हूं जो इस कर्सर का उपयोग करता है। हालांकि, मैं इस अपवाद के साथ रुक-रुक कर दुर्घटनाओं हो रही है:एक कर्सर का उपयोग एक AsyncTask

android.database.StaleDataException: Attempted to access a cursor after it has been closed. 

मेरे संदेह है कि इस वजह से कर्सर (यूआई थ्रेड में लोडर द्वारा प्रबंधित किया जा) हो रहा है से पहले पृष्ठभूमि धागे से समाप्त हो गया है बंद कर दिया जा रहा है यह, क्योंकि यह एक प्रबंधित कर्सर है।

private class LoaderListener implements LoaderManager.LoaderCallbacks<Cursor> { 
    @Override 
    public void onCreateLoader(int d, Bundle args) { 
     return new CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
     processCursor(cursor)  
    } 
} 

private void processCursor(final Cursor cursor) { 
    new AsyncTask<Void, Void, Result> { 
     @Override 
     Result doInBackground(Void... params) { 
      while(cursor.isAfterLast() == false) { 
       // doing some costly things with cursor 
      } 
     } 
    }.execute(); 
} 

यह या तो संभव है,

  1. किसी तरह यह यूआई धागे से बंद किया जा रहा से रोकने के लिए कर्सर को चिह्नित करता: यहां कुछ भावानूदित कोड है।

  2. प्रबंधक कि कर्सर भी उपयोग में है सूचित करें।

  3. क्लोन यह इतना है कि क्लोन उदाहरण प्रबंधक द्वारा बंद कर दिया नहीं होती है।

  4. एक और भी बेहतर, समाधान?

यूआई थ्रेड पर किया गया यह पोस्ट-प्रोसेसिंग पूरी तरह से एक विकल्प नहीं है, हालांकि, यह बहुत महंगा हो सकता है।

+1

आप हमेशा 'कर्सर लोडर' को छोड़ सकते हैं और प्रारंभिक क्वेरी + 'AsyncTask' में महंगी प्रसंस्करण कर सकते हैं। – Luksprog

+0

क्या आप इस कर्सर का उपयोग किसी और चीज़ के लिए कर रहे हैं? – njzk2

उत्तर

2

क्या किसी भी तरह से कर्सर को यूआई थ्रेड से बंद होने से रोकने के लिए ध्वजांकित करना संभव है?

नहीं (ठीक है, आंतरिक एपीआई को फिर से लिखने के बिना नहीं)।

क्या यह संभव है प्रबंधक को सूचित करने के लिए कि कर्सर भी उपयोग में है?

एक ही जवाब के रूप में इसके बाद के संस्करण।

क्या यह क्लोन करना संभव है ताकि क्लोन इंस्टेंस प्रबंधक द्वारा बंद न हो?

यह गंदा की तरह लग रहा है ... और वहाँ अभी भी मौका है कि LoaderManager कर्सर बंद कर देता है इससे पहले कि आप क्लोनिंग खत्म करने के लिए सक्षम हैं।

वहाँ एक बेहतर समाधान है?

हां। LoaderManager पर जाने वाले किसी का पुन: उपयोग करने की कोशिश करने के बजाय एक नया कर्सर पूछें।

+0

क्या आप अधिक विशिष्ट हो सकते हैं? आपके उत्तर की मेरी समझ से, मुझे अभी भी नए कर्सर को पोस्ट-प्रोसेस करना होगा, जिससे एक ही समस्या हो सकती है ...? –

+0

क्या मैं पूछ सकता हूं कि आप क्या करने की कोशिश कर रहे हैं? ऐसा क्यों है कि आपका "पोस्ट-प्रोसेसिंग" एक साथ 'लोडर प्रबंधक' जीवन चक्र है? क्यों न सिर्फ उन्हें अलग से इलाज करें? यह इस तरह से बहुत साफ होगा ... –

0

मैन, मुझे एक ही समस्या का सामना करना पड़ रहा है। गतिविधि की ऑनस्ट्राय विधि में एसिन्टास्क को रद्द करना है।

private YourAsyncTask asyncTask 

@Override 
protected void onDestroy(){ 
    super.onDestroy(); 
    asyncTask.cancel(true); 
}