Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-notifyDataSetChanged()和线程_Android_Android Asynctask_Android Ui_Android Adapter - Fatal编程技术网

Android-notifyDataSetChanged()和线程

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()会显示“不幸的是,应用程序名称已停止工作”消息。我的错误堆

我有一个AsyncTask,它在
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我把“方法”理解为“实现的方法”: