Android(安卓)AsyncTaskLoader需要注意的问题
16lz
2021-01-25
在使用AsyncTaskLoader的时候,遇到两个问题:
1.继承AsyncTaskLoader并实现了必要的方法后,发现loadInBackground()没有被执行
在网上查找之后,得到如下解决方法:
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的代码:
更新ListView数据的操作都是发生在UI线程,所以应该是系统在我们不知道的地方更新了数据而没有通知ListView.
查看Activity.java的源码可以看到:
Activity恢复的时候,会重新调用onStart函数,从而最终调用到我们Loader里的onStartLoading函数,
而我们的onStartLoading函数是这样:
也就是说,不管如何,都会在后台将数据重新加载一遍,因为是系统调用的,所以没有通知ListView,造成数据的不同步.
到这里,解决方案就呼之欲出了:
改造如下:
1.继承AsyncTaskLoader并实现了必要的方法后,发现loadInBackground()没有被执行
在网上查找之后,得到如下解决方法:
继承AsyncTaskLoader后,需要重载以下方法供系统调用:
@Overrideprotected void onStartLoading() {// TODO Auto-generated method stubsuper.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函数是这样:
@Overrideprotected void onStartLoading() {// TODO Auto-generated method stubsuper.onStartLoading();forceLoad();}
也就是说,不管如何,都会在后台将数据重新加载一遍,因为是系统调用的,所以没有通知ListView,造成数据的不同步.
到这里,解决方案就呼之欲出了:
改造如下:
@Overrideprotected void onStartLoading() {// TODO Auto-generated method stubsuper.onStartLoading();if(data.size() == 0)forceLoad();}
更多相关文章
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- Pixel修改kernel内核调试
- android关于获取摄像头帧数据转成图片
- Android7.1修改系统默认多媒体音量大小
- Android数据存储(3)SQLite简介和简单的登录与注册源代码
- android 第一行代码(第二版)Litepal遇到的问题