3

我有一个从本地数据库CursorLoader加载数据的。SQLite

中的数据SQLite实际上是远程API响应的缓存副本,因此SQLite每当CursorLoader.

以下是我响应我的数据查询所遵循的步骤序列ContentProvider

  1. SQLite在返回的游标上cached data. cursor.setNotificationUri(getContext().getContentResolver(), uri)调用查询。

  2. 启动对 remote 的异步调用API。一旦收到响应,getContext().getContentResolver().notifyChange(uri, null)就会调用。

  3. 休眠5几秒钟以导致延迟接收光标CursorLoader。(这样做是为了轻松重现我的问题)。

  4. 将获得的光标返回Step 1CursorLoader.

在异步远程API调用完成(notifyChange()并被调用)的不太可能但可能的情况下,可以通过调用在获得的游标上CursorLoader注册 a [参见http://grepcode.com/file/repository.grepcode.com/java/ext /com.google.android/android/4.0.1_r1/android/content/CursorLoader.java#CursorLoader.loadInBackground%28%29 ],数据更改通知被遗漏,因此看不到更新的数据。ContentObserverregisterContentObserver(cursor, mObserver)CursorLoaderActivity

我可以通过编写LoaderCallBacks这样的方法来解决这个问题,即数据被加载两次——首先只加载缓存的数据,然后发出refresh请求。这样,在呼叫开始之前CursorLoader就可以注册。ContentObserverrefresh

但是,理想情况下,这应该由它CursorLoader自己处理,因为它会CursorLoader宣传游标的自动更新。每次都这样做Activity会导致Activity代码膨胀。

4

2 回答 2

1

我的方法是在开始加载光标之前注册观察者。您需要注册 Uri 而不是光标。

 getActivity().getContentResolver().registerContentObserver(
 your_Uri, true,
 new YourObserver(mHandler));

getLoaderManager().initLoader(0, null, this);
于 2013-07-28T22:14:44.540 回答
0

在初始化时获取对加载器的引用,如下所示

Loader dayWeatherLoader = getLoaderManager().initLoader(LOADER_DAY_WEATHER, null, this);

然后创建一个扩展 ContentObserver 的类,如下所示

class DataObserver extends ContentObserver {

public DataObserver(Handler handler) {
    super(handler);
}

@Override
public void onChange(boolean selfChange, Uri uri) {
    dayWeatherLoader.forceLoad();
}
}

然后在 onResume 生命周期方法中注册内容观察者如下

@Override
public void onResume() {
super.onResume();
getContext().getContentResolver().registerContentObserver(CONTENTPROVIDERURI,true,new DayWeatherDataObserver(new Handler()));
}

每当 content provider 底层数据发生变化时,就会调用 contentobserver 的 onChange 方法,可以让 loader 重新加载数据

于 2017-03-09T01:38:22.683 回答