为什么cursorLoader没有通知源数据中的更改? [英] Why cursorLoader didn't notify changes in source data?

查看:197
本文介绍了为什么cursorLoader没有通知源数据中的更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


Loader将监视数据的变化,并通过这里的新调用将它们报告给
。你不应该自己监视数据
例如,如果数据是一个Cursor你把它放在一个
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适配器;
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);

//准备加载器。要么重新连接一个现有的,
//或开始一个新的。
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){
//为正在显示的数据创建一个Cursor。
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){
//交换新的光标(框架将负责关闭
//一旦我们返回旧游标。)
adapter.swapCursor(data);
Log.i(TAG,I dati sono stati ricaricati);
}

public void onLoaderReset(Loader< Cursor> loader){
//当上面提供给onLoadFinished()
//的最后一个游标是即将关闭。我们需要确保我们没有
//使用它。
adapter.swapCursor(null);
}
}

有任何建议吗?


解决方案

AFAIK,您需要在 ContentProvider 中自行实施通知。为此,添加 getContext()。getContentResolver()。notifyChange(uri,null); 到 insert 更新删除方法并调用 .setNotificationUri(getContext()。getContentResolver(),uri) Cursor c $ c>,如官方文档这里可以找到整个图片。 / p>

注意:您不应关闭游标( cursor.close())要获得
关于更改的通知。


I have a simple contentProvider, a layout with a ListView and a button for adding Items in content Provider and a CursorLoader. The http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader, D) reference states that

The Loader will monitor for changes to the data, and report them to you through new calls here. You should not monitor the data yourself. For example, if the data is a Cursor and you place it in a CursorAdapter, use the CursorAdapter(android.content.Context, android.database.Cursor, int) constructor without passing in either FLAG_AUTO_REQUERY or FLAG_REGISTER_CONTENT_OBSERVER (that is, use 0 for the flags argument). This prevents the CursorAdapter from doing its own observing of the Cursor, which is not needed since when a change happens you will get a new Cursor throw another call here.

But the Log.info line in the onLoadFinished method was not executed and listView didn't refreshed. Here is my (simple) code:

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

Any suggestion?

解决方案

AFAIK, you need to implement notification yourself in ContentProvider. For this, add something like getContext().getContentResolver().notifyChange(uri, null); to insert,update and delete method of ContentProvider and invoke.setNotificationUri(getContext().getContentResolver(), uri) on your Cursor in queryas described in official documentation. Here you can find the whole picture.

Note: You should not close the cursor (cursor.close()) in order to get notifications about the changes.

这篇关于为什么cursorLoader没有通知源数据中的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆