Gop*_*ala 24 android android-loadermanager android-cursorloader
我一直在研究一个小的待办事项列表应用程序.我使用CursorLoader从内容提供者更新ToDolistview.我有一个函数onNewItemAdded(),当用户在文本视图中输入一个新项目并单击Enter时调用该函数.参考下文:
public void onNewItemAdded(String newItem) {
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(ToDoContentProvider.KEY_TASK, newItem);
cr.insert(ToDoContentProvider.CONTENT_URI, values);
// getLoaderManager().restartLoader(0, null, this); // commented for the sake of testing
}
@Override
protected void onResume() {
super.onResume();
//getLoaderManager().restartLoader(0, null, this); // commented for the sake of testing
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader loader = new CursorLoader(this,
ToDoContentProvider.CONTENT_URI, null, null, null, null);
Log.e("GOPAL", "In the onCreateLoader");
return loader;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
int keyTaskIndex = cursor.getColumnIndexOrThrow(ToDoContentProvider.KEY_TASK);
Log.e("GOPAL", "In the onLoadFinished");
todoItems.clear();
if (cursor.moveToNext() == false) Log.e("GOPAL", "Empty Cursor");
else {
while (cursor.moveToNext()) {
ToDoItem newItem = new ToDoItem(cursor.getString(keyTaskIndex));
todoItems.add(newItem);
}
aa.notifyDataSetChanged(); // aa is arrayadapter used for the listview
}
}
Run Code Online (Sandbox Code Playgroud)
我已经读过,只要内容提供程序db中有数据更改,CursorLoader就会自动更新视图.这意味着我想,getLoaderManager().restartLoader(0, null, this)只要数据发生变化,就必须隐式调用,对吧?但那并没有发生.每当我添加一个新项目(该项目被添加到数据库中onNewItemAdded,但未明确调用restartLoader)时,请暂停此活动并将其恢复.我没有看到对restartLoader的任何隐式调用(即使db已更改),并且listview也没有更新添加新项目.这是为什么?CursorLoader即使应用程序未处于活动状态,如何自动更新视图?谢谢 :)
编辑:我也用于getContext().getContentResolver().notifyChange(insertedId, null)插入我的内容提供商.
Gop*_*ala 71
我找到了问题的答案.通常,CursorLoader不会自动检测数据更改并将其加载到视图中.我们需要跟踪URI以进行更改.这可以通过以下步骤完成:
使用以下内容通过游标在内容解析程序中注册Observer :(在ContentProvider的查询方法中完成)
cursor.setNotificationUri(getContext().getContentResolver(), uri);
现在,当使用insert()/ delete()/ 对URI基础数据进行任何更改时,update(),我们ContentResolver使用以下方式通知有关更改:
getContext().getContentResolver().notifyChange(insertedId, null);
这是由观察者接收到的,我们注册在第1步,这调用ContentResolver.query(),它依次调用ContentProvider的query()方法返回一个新的光标LoaderManager.LoaderManager调用onLoadFinished()传递此游标,以及CursorLoader我们Adapter.swapCursor()用新数据更新View(使用)的位置.
有时我们需要自定义加载器而不是CursorLoader.在这里,我们可以使用除光标之外的其他对象来指向加载的数据(如列表等).在此我们不会通过游标通知ContentResolver.应用程序也可能没有内容提供程序来跟踪URI更改.在这种情况下,我们使用BroadcastReceiver或显式ContentObserver来实现自动视图更新.具体如下:
AsyncTaskLoader并实现其所有抽象方法.与此不同CursorLoader,我们的自定义加载器可能会也可能不会使用内容提供程序,并且ContentResolver.query()当此加载程序被设置时,它的构造函数可能不会调用.所以我们使用广播接收器来达到目的.BroadCastReceiver或ContentObserver以OnStartLoading()抽象的方法AsyncTaskLoader类. onContentChanged()方法,以通知加载器有关数据更改的信息.Loader会自动完成剩下的工作以加载更新的数据并调用onLoadFinished()以更新视图.有关详细信息,请参阅:http://developer.android.com/reference/android/content/AsyncTaskLoader.html
我发现这对于明确的解释非常有用:http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html
| 归档时间: |
|
| 查看次数: |
21879 次 |
| 最近记录: |