如何CursorLoader自动更新,即使该应用程序是无效的看法?自动更新、应用程序、使该、看法

2023-09-03 23:04:50 作者:抒发失控的情绪″

我一直在一个小的待办事项列表应用程序。我用CursorLoader更新从内容提供商的ToDolistview。我有一个书面onNewItemAdded()函数,当用户进入一个新的项目,在文本视图,并点击进入被调用。参考如下:

I have been working on a small To-Do list app. I used CursorLoader to update the ToDolistview from a content provider. I have a written a function onNewItemAdded(), which is called when user enters a new item in the text view and clicks enter. Refer below:

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

我看了,CursorLoader自动更新视图,每当有内容提供商DB数据更改。这意味着我想,getLoaderManager()。restartLoader(0,空,这一点)已被隐式调用每当有数据的变化,对不对?           但这并没有发生。每当我添加一个新的项目(该项目被添加到从onNewItemAdded分贝,但restartLoader不显式调用),暂停本次活动,并恢复它回来。我没有看到restartLoader(即使数据库被改变)任何隐式调用和列表视图也不会更新与新加入的项目。这是为什么?如何做一个CursorLoader自动更新,即使应用程序是不活动的看法??? 感谢:)

I have read, CursorLoader automatically updates the view, whenever there is a data change in the content provider db. That means I suppose, getLoaderManager().restartLoader(0, null, this) has to be called implicitly whenever there is a change in data, right? But that is not happening. Whenever I add a new item (the item is added to the db from onNewItemAdded, but restartLoader is not explicitly called), pause this activity and resume it back. I don't see any implicit call to restartLoader(even though db is changed) and the listview also is not updated with new item added. Why is that? How does a CursorLoader automatically updates the view even if app is not active??? Thanks :)

编辑:。我也用的getContext()getContentResolver()有NotifyChange(insertedId,NULL)在我的内容提供商插入

I have also used getContext().getContentResolver().notifyChange(insertedId, null) in insert of my content provider.

推荐答案

我发现我的问题的答案。一般情况下,CursorLoader不会自动检测数据的变化,并加载它们来查看。我们需要跟踪的URI更改。这可以通过以下步骤来完成:

I found the answer for my question. In general, CursorLoader doesn't automatically detect data changes and load them to view. We need to track URI for changes. This can be done by following steps:

通过使用游标注册内容解析观察员:(ContentProvider的中的查询方法完成)   cursor.setNotificationUri(的getContext()getContentResolver(),URI); 现在,当有使用插入()的URI基础数据的任何更改/删除()/更新(),我们通知有关使用变化ContentResolver的:   。的getContext()getContentResolver()有NotifyChange(insertedId,NULL); 这是收到的观察者,我们注册在步骤1和此调用ContentResolver.query(),它依次调用Contentent供应商查询()方法返回一个新的游标loaderManager。 LoaderManager电话onLoadFinished通过这个指针,随着Cursorloader我们更新视图(使用adapter.swapcursor())用新的数据。 Registering an Observer in content resolver through cursor using: (Done in the query method of ContentProvider) cursor.setNotificationUri(getContext().getContentResolver(), uri); Now when there is any change in URI underlying data using insert()/delete()/update(), we notify the contentresolver about the change using: getContext().getContentResolver().notifyChange(insertedId, null); This is received by the observer, we registered in step-1 and this calls to ContentResolver.query(), which inturn calls Contentent providers query() method to return a fresh cursor to loaderManager. LoaderManager calls onLoadFinished passing this cursor, along with the Cursorloader where we update the View (using adapter.swapcursor()) with fresh data.

有时候,我们需要我们的自定义加载器,而不是CursorLoader。在这里,我们可以用someother对象而不是光标等指向加载的数据(如列表等)。在此,我们不会有previlige通过游标通知ContentResolver的。应用程序也可以不具有内容提供者,以跟踪的URI更改。在这种情况下,我们使用的BroadcastReceiver或明确ContentObserver实现自动视图updation。这是如下:

For Custom AsyncTaskLoaders:

At times we need our custom loader instead of CursorLoader. Here we can use someother object other than cursor to point to the loaded data (like list etc). In this we won't be having previlige to notify ContentResolver through cursor. The application may also not have a content Provider, to track URI changes. In this scenario we use BroadcastReceiver or explicit ContentObserver to achieve automatic view updation. This is as follows:

我们需要定义我们的自定义加载器延伸AsyncTaskLoader并实现所有的抽象方法。不同于CursorLoader,我们的自定义加载器可能会或不会使用的内容提供商,它的构造函数不能调用ContentResolver.query(),当该装载机instatiated。因此,我们使用的广播接收器为服务宗旨。 我们需要实例中OnStartLoading(一个BroadcastReceiver或ContentObserver抽象AsyncTaskLoader类的)方法。 在这个广播接收器应该被定义为接收来自内容提供商或系统事件(例如安装新的应用程序)的数据变化的广播,它必须调用装载机onContentChanged()方法,通知有关数据的变化装载机。装载机自动完成剩下来加载更新后的数据,并调用onLoadFinished()来更新视图。

有关详情请参阅本:http://developer.android.com/reference/android/content/AsyncTaskLoader.html

我发现这个有明确的解释非常有用:http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html

I found this very useful for clear explanation : http://www.androiddesignpatterns.com/2012/08/implementing-loaders.html