在使用AsyncTaskLoader的时候,遇到两个问题:
1.继承AsyncTaskLoader并实现了必要的方法后,发现loadInBackground()没有被执行
在网上查找之后,得到如下解决方法:
继承AsyncTaskLoader后,需要重载以下方法供系统调用:
@Override
protected void onStartLoading() {
// TODO Auto-generated method stub
super.onStartLoading();
forceLoad();
}
2.使用问题1的解决方案后,Loader开始工作了,但是又遇到了新的问题,我在Activity里面写了一个ListView,ListView的数据通过AsyncTaskLoader
来进行加载,当从当前Activity跳到另一个Activity并按back键返回时,此时没有问题,但是当点击ListView中的某一项时,报出以下的错误:
E/AndroidRuntime(1141): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(16908298, class android.widget.ListView) with Adapter(class com.study.ActivityAdapter)]
以下是我自定义AsyncTaskLoader的代码:
public class ActivityListLoader extends AsyncTaskLoader{
private Context context;
private Bundle args;
private String path;
private List
更新ListView数据的操作都是发生在UI线程,所以应该是系统在我们不知道的地方更新了数据而没有通知ListView.
查看Activity.java的源码可以看到:
protected void onStart() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
mCalled = true;
if (!mLoadersStarted) {
mLoadersStarted = true;
if (mLoaderManager != null) {
mLoaderManager.doStart(); //系统会执行Loader的onStartLoading函数
} else if (!mCheckedForLoaderManager) {
mLoaderManager = getLoaderManager(null, mLoadersStarted, false);
}
mCheckedForLoaderManager = true;
}
getApplication().dispatchActivityStarted(this);
}
Activity恢复的时候,会重新调用onStart函数,从而最终调用到我们Loader里的onStartLoading函数,
而我们的onStartLoading函数是这样:
@Override
protected void onStartLoading() {
// TODO Auto-generated method stub
super.onStartLoading();
forceLoad();
}
也就是说,不管如何,都会在后台将数据重新加载一遍,因为是系统调用的,所以没有通知ListView,造成数据的不同步.
到这里,解决方案就呼之欲出了:
改造如下:
@Override
protected void onStartLoading() {
// TODO Auto-generated method stub
super.onStartLoading();
if(data.size() == 0)
forceLoad();
}