为什么cursorLoader没有通知源数据的变化?

时间:2011-12-29 12:38:44

标签: android cursor simplecursoradapter

我有一个简单的contentProvider,一个带有ListView的布局和一个用于在内容提供者和CursorLoader中添加项目的按钮。 http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader,D)引用指出

  

Loader将监控数据的更改,并将其报告给   你通过这里的新电话。您不应该自己监控数据。   例如,如果数据是Cursor,则将其放在a中   CursorAdapter,使用CursorAdapter(android.content.Context,   android.database.Cursor,int)构造函数,没有传入任何一个   FLAG_AUTO_REQUERY或FLAG_REGISTER_CONTENT_OBSERVER(即使用0   对于flags参数)。这可以防止CursorAdapter执行操作   它自己观察Cursor,这是一个不需要的   改变发生你会得到一个新的Cursor在这里抛出另一个调用。

但是onLoadFinished方法中的Log.info行没有执行,listView没有刷新。这是我的(简单)代码:

public class HomeActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>{
static final String TAG = "HomeActivity";
SimpleCursorAdapter adapter;
ListView listAnnunciVicini;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    listAnnunciVicini = (ListView) findViewById(R.id.lista_annunci_vicini);

    adapter = new SimpleCursorAdapter(this, R.layout.list_item, null, 
            new String[] {
                    ContentDescriptor.Annunci.Cols.ID, 
                    ContentDescriptor.Annunci.Cols.TITOLO, 
                    ContentDescriptor.Annunci.Cols.DESCRIZIONE 
            }, new int[] { 
                    R.id.list_annunci_item_id_annuncio, 
                    R.id.list_annunci_item_titolo_annuncio,
                    R.id.list_annunci_item_descrizione_annuncio
            }, 0);
    listAnnunciVicini.setAdapter(adapter);

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

public void addRandomItem(View sender) {
    ContentValues dataToAdd = new ContentValues();
    dataToAdd.put(ContentDescriptor.Annunci.Cols.TITOLO, "Titolo");
    dataToAdd.put(ContentDescriptor.Annunci.Cols.DESCRIZIONE, "Lorem ipsum dolor sit amet.");
    this.getContentResolver().insert(ContentDescriptor.Annunci.CONTENT_URI, dataToAdd);
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // creating a Cursor for the data being displayed.
    String[] proiezione = new String[] {ContentDescriptor.Annunci.Cols.ID, ContentDescriptor.Annunci.Cols.TITOLO, ContentDescriptor.Annunci.Cols.DESCRIZIONE };

    CursorLoader cl = new CursorLoader(this, ContentDescriptor.Annunci.CONTENT_URI, proiezione, null, null, null);
    return cl;
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Swap the new cursor in.  (The framework will take care of closing the
    // old cursor once we return.)
    adapter.swapCursor(data);
    Log.i(TAG, "I dati sono stati ricaricati");
}

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.
    adapter.swapCursor(null);
}
}

有什么建议吗?

1 个答案:

答案 0 :(得分:20)

AFAIK,您需要自己在ContentProvider中实施通知。为此,在getContext().getContentResolver().notifyChange(uri, null);上添加insertupdatedeleteContentProvider .setNotificationUri(getContext().getContentResolver(), uri)方法,并在Cursor上调用query cursor.close()中所述的{{1}} { official documentation你可以找到全貌。

注意:您不应该关闭光标({{1}})以获取  有关更改的通知。