为什么cursorLoader没有通知源数据中的更改? [英] Why cursorLoader didn't notify changes in source data?
问题描述
我有一个简单的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,您需要在 注意:您不应关闭游标( 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: Any suggestion? AFAIK, you need to implement notification yourself in Note: You should not close the cursor ( 这篇关于为什么cursorLoader没有通知源数据中的更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! ContentProvider
中自行实施通知。为此,添加 getContext()。getContentResolver()。notifyChange(uri,null); 到
insert
更新
和删除
方法并调用
.setNotificationUri(getContext()。getContentResolver(),uri)
在 Cursor
c $ c>,如官方文档。 这里可以找到整个图片。 / p>
cursor.close()
)要获得
关于更改的通知。
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);
}
}
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 query
as described in official documentation. Here you can find the whole picture.cursor.close()
) in order to get
notifications about the changes.