2012-01-18 17 views
5

मैं कर्सर लोडर (v4 संगतता लाइब्रेरी का उपयोग करके) का उपयोग करने के लिए एक एंड्रॉइड 2.2 एप्लिकेशन अपडेट कर रहा हूं और मैं समझने की कोशिश कर रहा हूं कि onLoadFinished विधि प्रदाता क्यों प्रदाता नहीं है CursorLoader क्वेरी से जुड़े सामग्री में बदलाव को सूचित करता है।एंड्रॉइड कर्सरलोडर ContentProvider अधिसूचनाओं का जवाब नहीं दे रहा है

CursorLoader एक ग्राहक सामग्री प्रदाता की क्वेरी है। मेरे प्रदाता अधिसूचना यूआरआई सेट अपनी क्वेरी विधि में:

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

और उसके सम्मिलित/अपडेट करने में परिवर्तन को सूचित करता है/हटाना तरीके:

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

मैं देख लिया है कि यूआरआई दोनों ही मामलों में समान है। पहले मैं एक ही सामग्री प्रदाता के साथ एक प्रबंधित प्रोग्राम का उपयोग कर रहा था और पूछताछ की गई सामग्री ठीक से अपडेट की गई थी, जो मुझे लगता है कि सामग्री प्रदाता शायद ठीक है।

मैंने LoaderCursorSupport उदाहरण देखा है और दिलचस्प बात यह है कि जब मैं इसे अपने नेक्सस वन पर चलाता हूं तो मुझे यह नहीं दिखता है कि मैं उन संपर्कों को प्रतिबिंबित करता हूं जो मैं नामों से संपर्क करता हूं (उदाहरण ऐप और संपर्क ऐप के बीच स्विचिंग)। इसे होना चाहिए? यदि हां, तो क्या कुछ अंतर्निहित समस्या है जिसके बारे में मुझे पता नहीं है?

+0

क्या आप समस्या को पिन-पॉइंट करने में हमारी सहायता के लिए कुछ कोड प्रदान कर सकते हैं? –

+0

को सक्षम करने से डिबगिंग मदद कर सकता है, 'LoaderManager.enableDebugLogging (सही)' –

+0

डिबगिंग टिप के लिए धन्यवाद। मेरा क्लाइंट कोड अनिवार्य रूप से लोडर कर्सर समर्थन उदाहरण जैसा ही संदर्भित है। यह देखते हुए कि इस एक ही समस्या दर्शाती है, मैं गलत समझा कैसे CursorLoader यानी काम करने के लिए अगर मैं संपर्कों की सूची दिखाने के लिए है, तो पता पुस्तिका में संपर्क को संपादित समर्थन उदाहरण चलाने माना जाता है है यह द्वारा प्रदर्शित सूची में नहीं बदलना चाहिए उदाहरण ऐप? – siwatson

उत्तर

-1

शायद तुम आवेदन संदर्भ का उपयोग करना चाहिए:

getContext().getApplicationContext().getContentResolver().notifyChange(uri, null); 
+0

यह कोई फर्क मुझे डर लग रहा नहीं किया। – siwatson

4

मैं अंत में इस की तह तक गया और, के रूप में आम तौर पर जिस तरह से है, यह मेरी ओर से एक मूर्ख गलती थी। एक ManagedQuery का उपयोग करने से एक बचे हुए मैं वापस आ कर्सर का उपयोग एक ArrayAdapter (मैं मैन्युअल रूप से सूची के शीर्ष पर एक आइटम डालने की आवश्यकता) और कर्सर पास बनाने के लिए किया गया था - मैं अपने onLoadFinished() विधि में cursor.close() कॉल किया गया था CursorLoader का उपयोग करने के लिए माइग्रेट करने से पहले।

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

package com.test; 

import android.content.ContentValues; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.provider.Browser; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.ListFragment; 
import android.support.v4.app.LoaderManager; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 
import android.support.v4.view.MenuItemCompat; 
import android.support.v4.widget.SimpleCursorAdapter; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 

public class CursorLoaderTestActivity extends FragmentActivity 
{ 
    private static final String TAG = CursorLoaderTestActivity.class.getSimpleName(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     FragmentManager fm = getSupportFragmentManager(); 

     // Create the list fragment and add it as our sole content. 
     if (fm.findFragmentById(android.R.id.content) == null) 
     { 
      CursorLoaderListFragment list = new CursorLoaderListFragment(); 
      fm.beginTransaction().add(android.R.id.content, list).commit(); 
     } 
    } 


    public static class CursorLoaderListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> 
    { 

     // This is the Adapter being used to display the list's data. 
     SimpleCursorAdapter mAdapter; 

     // If non-null, this is the current filter the user has provided. 
     String mCurFilter; 

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

      // Give some text to display if there is no data. In a real 
      // application this would come from a resource. 
      setEmptyText("No data"); 

      // We have a menu item to show in action bar. 
      setHasOptionsMenu(true); 

      // Create an empty adapter we will use to display the loaded data. 
      mAdapter = new SimpleCursorAdapter(getActivity(), 
        android.R.layout.simple_list_item_1, null, 
        new String[] { Browser.BookmarkColumns.TITLE }, 
        new int[] { android.R.id.text1}, 0); 

      setListAdapter(mAdapter); 

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

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

     //@Override 
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
     { 
      // Place an action bar item for searching. 
      MenuItem item = menu.add("Add Item"); 
      //item.setIcon(android.R.drawable.ic_menu_search); 
      MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); 
     } 

     @Override 
     public boolean onOptionsItemSelected (MenuItem item) 
     { 
      ContentValues cv=new ContentValues(); 
      cv.put(Browser.BookmarkColumns.TITLE, "!AA " + System.currentTimeMillis()); 
      cv.put(Browser.BookmarkColumns.URL, "http://test/"); 
      cv.put(Browser.BookmarkColumns.BOOKMARK, 1); 
      getActivity().getContentResolver().insert(Browser.BOOKMARKS_URI, cv); 
      return true; 
     } 

     //columns to query 
     static final String[] PROJECTION = new String[] { Browser.BookmarkColumns.TITLE }; 


     public Loader<Cursor> onCreateLoader(int id, Bundle args) 
     { 
      Log.i(TAG, "onCreateLoader"); 

      return new CursorLoader(getActivity(), Browser.BOOKMARKS_URI, 
        PROJECTION, null, null, 
        Browser.BookmarkColumns.TITLE + " ASC"); 
     } 

     public void onLoadFinished(Loader<Cursor> loader, Cursor data) 
     { 
      Log.i(TAG, "onLoadFinished"); 

      // 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); 
     } 

     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); 
     } 
    } 

} 
+0

हां। कर्सर जिंदा रखा जाना चाहिए जब तक एक और onLoadFinished में आपूर्ति की है()। – f470071

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