Android 如何使用CursorAdapter和LoaderCallbacks在片段中实现ContentObserver?

Android 如何使用CursorAdapter和LoaderCallbacks在片段中实现ContentObserver?,android,android-contentprovider,android-cursoradapter,android-cursorloader,contentobserver,Android,Android Contentprovider,Android Cursoradapter,Android Cursorloader,Contentobserver,我在ListFragment中使用游标适配器来加载和显示注释列表 public class CommentsFragment extends ListFragment implements LoaderCallbacks<Cursor> { protected Activity mActivity; protected CursorAdapter mAdapter; @Override public void onActivityCreated(B

我在ListFragment中使用游标适配器来加载和显示注释列表

public class CommentsFragment extends ListFragment implements LoaderCallbacks<Cursor> {

    protected Activity mActivity;
    protected CursorAdapter mAdapter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mActivity = getActivity();
        mAdapter = new CommentsCursorAdapter(mActivity, null, 0);
        setListAdapter(mAdapter);
        mActivity.getContentResolver().registerContentObserver(CustomContract.Comments.CONTENT_URI, false, new CommentsObserver());
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle extras) {
        Uri uri = CustomContract.Comments.CONTENT_URI;
        return new CursorLoader(mActivity, uri, null, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        mAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }

    protected class CommentsObserver extends ContentObserver {

        public CommentsObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            // TODO Trigger a reload.
        }

    }
}
问题:

将null传递给notifyChange作为观察者参数可以吗?如果没有,我应该通过什么物体? 我应该在notifyChange中传递uri还是itemUri?为什么? 我必须调用CommentsObserveronChange中的什么方法来更新注释列表? 是否没有可以用ListFragment而不是ContentObserver的内部类实例实现的接口? 我只是在CommentsObserver的构造函数中实例化一个新的处理程序。这对我来说似乎不正确——请解释一下。 SqlCursor已经有了内部ContentObserver,因为您正在使用这个游标实现,所以不需要自己的ContentObserver实现

为便于使用,您可以添加:

class MyContentProvider extends ContentProvider{
  //rest implementation goes here
  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
    Cursor cursor = null;
    //check uri, select table name based on uri, etc ...
    cursor = db.query(/*.....*/);
    //add this line:
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    //before you return cursor
    return cursor;
  }
  @Override
  public Uri insert(Uri uri, ContentValues values) {
     /* ... */
       //you can notify only "dir" uri and is should be enough
       getContext().getContentResolver().notifyChange(uri, null);
       return itemUri;
     /* ... */
  }
  //rest of implementation goes here
}

在此之后,CursorLoader内部实现将负责重新加载/刷新数据…

好的,我完成了。。。你可以试试我的图书馆。。。是的,它打算与MSFT一起使用。。。但它也可以在没有它的情况下工作。。。您可以删除所有同步代码,然后从注释中获得easy runtime ContentProvider generator库:我来看看。再次谢谢你。检查一下。。。我剥离了同步代码并制作了示例projectI,但我遇到了类似的问题,我在没有ContentObserver的情况下实现了我的ListFragment,并且我的ListView没有更新。当前,当创建片段时,它启动并意图服务来查询服务器以获取更新的数据,同时显示本地SQLLite数据库中的旧数据。检索时,它更新本地数据库并通知更改。在我的第一个ContentObserver onChange实现中,我在SimpleCursorAdapter上调用notifyDataSetChanged。我也尝试过上面的设计,但仍然没有更新。当我重新创建活动和片段时,它会显示新数据。您使用的是CursorLoader吗?您在从云代码检索时是否使用了CP的更新方法?我使用的是游标加载器,在连接到云的服务中,它执行插入,getContentResolver.insertUri.withAppendedPathMyProvider.CONTENT\u URI,表名,值;该insertsWithOnConflict的执行基于一个唯一的字段并进行更新。所以它通常会进行更新。您确定insert和selectnew CursorLoader…,uri…,中的uri相同吗。。。和getContentResolver.inserturi,…,接下来,您是否添加了我在回答中提到的插入/更新中的notifyChange和选择中的setNotificationUri中的行…为了检查自动刷新机制是否工作,请添加代码为getContentResolver.notifyChangeuri的按钮/菜单,null;到您的列表片段。。。我很确定它会起作用。。。无论如何,在我仔细检查了URI之后,请检查我对问题的第二个注释中的代码,以及对CP上的URI的通知。在服务中插入后通知解决了我的问题。谢谢你的线索!
class MyContentProvider extends ContentProvider{
  //rest implementation goes here
  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
    Cursor cursor = null;
    //check uri, select table name based on uri, etc ...
    cursor = db.query(/*.....*/);
    //add this line:
    cursor.setNotificationUri(getContext().getContentResolver(), uri);
    //before you return cursor
    return cursor;
  }
  @Override
  public Uri insert(Uri uri, ContentValues values) {
     /* ... */
       //you can notify only "dir" uri and is should be enough
       getContext().getContentResolver().notifyChange(uri, null);
       return itemUri;
     /* ... */
  }
  //rest of implementation goes here
}