Android-notifyDataSetChanged()和线程
我有一个AsyncTask,它在Android-notifyDataSetChanged()和线程,android,android-asynctask,android-ui,android-adapter,Android,Android Asynctask,Android Ui,Android Adapter,我有一个AsyncTask,它在doInBackground()方法中执行一些数字运算(在接下来的几行中有更多详细信息)。doInBackground()中操作的数据是与ListView的适配器相关联的数据(在我的例子中是一个simpledapter)。处理适配器数据后,我需要调用notifyDataSetChanged()并更新我的ListView。但是在doInBackground()中调用notifyDataSetChanged()会显示“不幸的是,应用程序名称已停止工作”消息。我的错误堆
doInBackground()
方法中执行一些数字运算(在接下来的几行中有更多详细信息)。doInBackground()
中操作的数据是与ListView的
适配器相关联的数据(在我的例子中是一个simpledapter
)。处理适配器数据后,我需要调用notifyDataSetChanged()
并更新我的ListView
。但是在doInBackground()
中调用notifyDataSetChanged()
会显示“不幸的是,应用程序名称已停止工作”消息。我的错误堆栈显示如下:
06-22 08:01:49.083:E/AndroidRuntime(9955):致命异常:AsyncTask#2
06-22 08:01:49.083:E/AndroidRuntime(9955):java.lang.RuntimeException:执行doInBackground()时出错
06-22 08:01:49.083:E/AndroidRuntime(9955):在android.os.AsyncTask$3.done(AsyncTask.java:299)
06-22 08:01:49.083:E/AndroidRuntime(9955):在java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
06-22 08:01:49.083:E/AndroidRuntime(9955):位于java.util.concurrent.FutureTask.setException(FutureTask.java:219)
06-22 08:01:49.083:E/AndroidRuntime(9955):在java.util.concurrent.FutureTask.run(FutureTask.java:239)
06-22 08:01:49.083:E/AndroidRuntime(9955):在android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-22 08:01:49.083:E/AndroidRuntime(9955):位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-22 08:01:49.083:E/AndroidRuntime(9955):位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-22 08:01:49.083:E/AndroidRuntime(9955):在java.lang.Thread.run(Thread.java:838)处
06-22 08:01:49.083:E/AndroidRuntime(9955):原因:android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图
最后一行
06-22 08:01:49.083:E/AndroidRuntime(9955):原因:android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图
提供我需要调试的信息。我通过从onPostExecute()
调用notifyDataSetChanged()
解决了这个问题,但我仍然不明白这个方法实际上是如何工作的。我的问题是:
问题1。notifyDataSetChanged()
实际上是如何更新UI的
问题2。notifyDataSetChanged()
与UI线程之间的连接是什么
第三季度。是否有任何方法可以在工作线程上调用notifyDataSetChanged()
我是一个Android的初学者,对于这些基本问题的任何帮助都将不胜感激。我的网络搜索没有给我想要的答案。也非常感谢您抽出时间
How does notifyDataSetChanged() actually update the UI ?
它会更改以前添加的ListView项,从而实际更改UI
示例:将添加/删除到传递给适配器的数组
时
What is the connection between notifyDataSetChanged() and the UI thread ?
当您从UI线程创建视图时,它是唯一一个可以更新/更改视图的线程,没有其他功能。如果您尝试从其他线程更新视图,则会出现以下错误:calledFromErrorThreadException
Is there any method in which notifyDataSetChanged() can be called on a worker thread ?
是的,您可以调用活动的runOnUiThread
来调用主/UI线程以更新ListView
示例:
runOnUiThread(new Runnable() {
@Override
public void run() {
//notifyDataSetChanged here or update your UI on different thread
}
});
问题1。notifyDataSetChanged()实际上是如何更新UI的
实际上,notifyDataSetChanged()
只在其关联的观察器上激发onChanged()
方法。对于AdapterView
子类(例如ListView
),这将调用requestLayout()
,它将
这意味着ListView
不会“立即”重新创建其子视图,但只要UI线程可以自由处理消息,它就会这样做。最终,将为每个项目调用getView()
问题2。notifyDataSetChanged()和UI之间的连接是什么
线
基本上,不允许从后台线程修改适配器的内容notifyDataSetChanged()
只是通知AdapterView
其数据已更改,应重新绘制的一种方式
第三季度。是否存在可以调用notifyDataSetChanged()的方法
在工作线程上
实际上,有几个。您可以在异步任务中使用或。更好地覆盖onProgressUpdate,并从doInBackground调用publishProgress()来更新UI。我不理解您对问题3的回答。他明确要求提供一个可以在工作线程上调用的方法,并且可以在其中调用notifyDataSetChanged()。您已经给出了在UI线程上运行的方法的答案。@Raymond232我把“方法”理解为“实现的方法”: