2013-06-12 6 views
6

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

जब मैं अंतर्निहित डेटा बदलता हूं, तो सूचीदृश्य onLoadFinished(Loader<Cursor>, Cursor) कॉल बैक के रूप में पुन: पॉप्युलेट नहीं होता है।

जैसा कि मैंने यह लिखते हुए सुझाव दिया है, इस मुद्दे पर बहुत सारे प्रश्न हैं। जैसे CursorLoader not updating after data change

और सभी सवालों के दो बातें कहना:

  • अपनी सामग्री प्रदाता क्वेरी() विधि में, आप a'la सूचनाओं के बारे में कर्सर बताने की आवश्यकता

c.setNotificationUri(getContext().getContentResolver(), uri);

  • अपनी सामग्री प्रदाता डालने/अपडेट/हटाने विधि में, आपको n यूआरआई पर otify:

getContext().getContentResolver().notifyChange(uri, null);

मैं उन चीजों कर रहा हूँ।

मैं किसी भी कर्सर को वापस बंद नहीं कर रहा हूं।

नोट, मेरा सामग्री प्रदाता एक अलग ऐप में रहता है (इसे सामग्री प्रदाता ऐप के रूप में सोचें - कोई लॉन्चर मुख्य गतिविधि नहीं)। एक com.example.provider एपीके, और com.example.app सामग्री के माध्यम से (सामग्री समाधानकर्ता में) कॉल कर रहा है: //com.example.provider/table यूआरआई आदि। सामग्री रिज़ॉल्वर (dbhelper) लाइब्रेरी प्रोजेक्ट में रहता है (com.example.appdb) जिसमें गतिविधि लिंक है। (इस तरह, एकाधिक प्रोजेक्ट्स लिंकिंग के माध्यम से डबेलर का उपयोग कर सकते हैं, और सभी सामग्री प्रदाता एकल एपीके के माध्यम से स्थापित किए जाते हैं)

मैंने लोडर प्रबंधक में डिबगिंग चालू कर दी है, और डेटा परिवर्तन के बाद मैं ताज़ा करने के लिए कहां ताज़ा कर सकता हूं (यानी लोडर को पुनरारंभ किया जा रहा है और पिछला निष्क्रिय किया जा रहा है), लेकिन कुछ भी नहीं कहता है कि कुछ भी स्वचालित रूप से हो रहा है - बल्कि, मेरे बल को ताज़ा करने के जवाब में।

कोई भी विचार क्यों मेरे लोडर को ताज़ा नहीं किया जा रहा है?

- संपादित करें -

लोडर बनाएँ:

Log.d(TAG, "onCreateLoader ID: " + loaderID); 
// typically a switch on the loader ID, and then 
return dbHelper.getfoo() 

कहाँ getfoo() के माध्यम से एक कर्सर लोडर रिटर्न:

return new CursorLoader(context, FOO_URI, foo_Fields, foo_query, foo_argArray, foo_sort);

लोडर समाप्त कर्सर और भरता लेता है एक टेबल (और कुछ प्रसंस्करण करता है) - वहां कुछ भी नहीं है।

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    Log.d(TAG, "onLoadFinished id: " + loader.getId()); 
    // switch on loader ID .. 
    FillTable(cursor, (FooAdapter) foo_info.listview.getAdapter(); 

लोडर रीसेट तालिका को साफ़ करता है।

public void onLoaderReset(Loader<Cursor> loader) { 
    Log.d(TAG, "onLoaderReset id: " + loader.getId()); 
    // normally a switch on loader ID 
    ((FooAdapter)foo_info.listview.getAdapter()).clear(); 

सामग्री प्रदाता करता है:

सार्वजनिक कर्सर क्वेरी (उरी uri, String [] प्रक्षेपण, स्ट्रिंग चयन, String [] selectionArgs, स्ट्रिंग sortOrder) { कर्सर कर्सर; SQLiteQueryBuilder qb = नया SQLiteQueryBuilder();

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     qb.setTables(FOO); 
     qb.setProjectionMap(FooProjectionMap); 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 

    c.setNotificationUri(getContext().getContentResolver(), uri); 
    return c; 

}

फिर/अपडेट करने सम्मिलित समान है:

public Uri insert(Uri uri, ContentValues initialValues) { 
    ContentValues values; 
    if (initialValues != null) { 
     values = new ContentValues(initialValues); 
    } else { 
     values = new ContentValues(); 
    } 

    String tableName; 
    Uri contentUri; 

    switch (sUriMatcher.match(uri)) { 
    case FOO: 
     tableName = FOOTABLE; 
     contentUri = FOO_URI; 
     break; 

    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    SQLiteDatabase db = dbHelper.getWritableDatabase(); 
    long rowId = db.insert(tableName, null, values); 
    if (rowId > 0) { 
     Uri objUri = ContentUris.withAppendedId(contentUri, rowId); 
     getContext().getContentResolver().notifyChange(objUri, null); 
     return objUri; 
    } 

    throw new SQLException("Failed to insert row into " + uri); 
} 
+0

कर्सर लोडर से संबंधित अपने कुछ कोड पोस्ट करने से मदद मिल सकती है। मुख्य रूप से आपके ऑनक्रेट लोडर, ऑनलोडर रीसेट और ऑनलोड परिभाषित विधियां। मुझे लगता है कि आपका ContentProvider अधिसूचना तक पहुंचता है जब आप रीफ्रेश करते हैं तो बदलें कॉल करें। – AfzalivE

+0

क्षमा करें, तूफान/बिजली आउटेज इत्यादि ने मुझे कुछ समय तक दूर रखा। –

उत्तर

2

मैं देख रहा हूँ कि आप अपने onLoadFinished और onLoaderReset में swapCursor या changeCursor बुला नहीं कर रहे हैं। आपको अपने एडाप्टर के लिए नए कर्सर में लोड किए गए डेटा तक पहुंचने के लिए ऐसा करने की ज़रूरत है।

onLoadFinished में

, की तरह कुछ फोन:

mAdapter.swapCursor(cursor) 

onLoaderReset में, यह फोन पुराने कर्सर को संदर्भ हटाने के लिए:

mAdapter.swapCursor(null) 

कहाँ mAdapter अपने ListView के एडाप्टर है।

और जानकारी: http://developer.android.com/guide/components/loaders.html#onLoadFinished

+0

मैंने अपने कोड में पहला उदाहरण चुना होगा, एक जहां यह एक सरणी एडाप्टर है, क्योंकि हमें कर्सर में नहीं है, और न ही डीबी में कर्सर से आता है (यानी यह एक अलग डेटाबेस में है, इसलिए मैं क्वेरी में जॉइन का उपयोग नहीं कर सकता)। कई अन्य सरल कर्सरडैप्टर (या सरल कर्सर से व्युत्पन्न) हैं ** ** ** ** लौटाए गए डेटा पर 'swapCursor() 'करें (और स्वतः रीफ्रेश न करें)। –

+0

क्या आप एक सरल कर्सर एडाप्टर का उपयोग कर रहे हैं और फिर अतिरिक्त जानकारी देख रहे हैं? मुझे लगता है कि आप एक कस्टम एडाप्टर का उपयोग कर बेहतर हो सकते हैं जो एडाप्टर क्लास में उस अतिरिक्त लुकअप करता है। मुझे उन अन्य लोगों को देखना होगा जो 'swapCursor()' को कॉल करते हैं लेकिन ताज़ा नहीं होते क्योंकि उनके पास कोई अन्य समस्या हो सकती है। – AfzalivE

2

तो, किसी के लिए भी है जो इस करता है और इस समस्या है:

निश्चित है कि यूआरआई आप पर कर्सर रजिस्टर करें, और यूआरआई आप कर्सर को सूचित कर रहे हैं वही।

मेरे मामले में, मैं अंतर्निहित तालिका को संशोधित करने वाले अन्य कोड में उपयोग किए जाने के बजाय क्वेरी के लिए एक अलग यूआरआई का उपयोग कर रहा था। अधिसूचना कार्य करने के लिए कोई आसान फिक्स नहीं था, इसलिए मैंने लोडर को ऑनर्यूसम() में समाधान के रूप में रीसेट कर रखा।

1

यह इस विशिष्ट समस्या का सीधा जवाब नहीं है, लेकिन अन्य लोगों की समान स्थिति में मदद कर सकता है। मेरे मामले में, मैं एक जुड़ाव था और भले ही मैंने प्रक्षेपण और क्वेरी में पूर्ण tablename.columnname का उपयोग किया था। यह वैसे भी गलत आईडी मूल्यों का उपयोग कर समाप्त हो गया। तो अपने ContentProvider या SQL वाक्यविन्यास की जांच करना सुनिश्चित करें।

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