Android - notifyDataSetChanged()和线程

use*_*702 5 android android-ui android-adapter android-asynctask

我有一个AsyncTask,它在doInBackground()方法中进行一些数字运算(在接下来的几行中有更多细节).操纵doInBackground()的数据是与ListView's适配器相关的数据(SimpleAdapter在我的例子中).处理适配器数据后我需要做的就是调用notifyDataSetChanged()并更新我的数据ListView.但是notifyDataSetChanged()在内部调用doInBackground()会显示"不幸'应用名称已停止工作"消息.我的错误堆栈显示了这个:

06-22 08:01:49.083:E/AndroidRuntime(9955):FATAL EXCEPTION: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): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)06-22 08:01:49.083:E/AndroidRuntime(9955):at java.util.concurrent.FutureTask.setException(FutureTask.java:219) 06-22 08:01:49.083:E/AndroidRuntime(9955):at java.util.concurrent.FutureTask.run(FutureTask.java:239)06-22 08:01:49.083:E/AndroidRuntime(9955):at android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:230)06-22 08:01:49.083:E/AndroidRuntime(9955):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 06-22 08:01:49.083:E/AndroidRuntime(9955):at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:573)06-22 08:01:49.083:E/AndroidRuntime(9955):at java.lang.Thread.run(Thread.java:838)06-22 08:01:49.083:E/AndroidRuntime(9955):引起:android.view.ViewRootImpl $ CalledFromWrongThreadException :只有创建视图层次结构的原始线程才能触及其视图.

最后一行

06-22 08:01:49.083:E/AndroidRuntime(9955):引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图.

给我调试所需的信息.我通过调用解决了这个问题notifyDataSetChanged(),从onPostExecute()但我还是不明白是怎么方法实际工作.我的问题是:

Q1.notifyDataSetChanged()实际上如何更新UI?

Q2.notifyDataSetChanged()UI线程和UI线程之间有什么联系?

Q3.有没有notifyDataSetChanged()可以在工作线程上调用的方法?

我是Android的初学者,对这些基本问题的任何帮助都将非常感激.我的互联网搜索没有给我我想要的答案.也非常感谢你的时间.

mat*_*ash 8

Q1.notifyDataSetChanged()如何实际更新UI?

实际上,notifyDataSetChanged()onChanged()在其相关的观察者上触发该方法.对于AdapterView子类(例如ListView),这最终会调用requestLayout(),它会调度视图树的布局过程.

这意味着ListView它不会"立即"重新创建其子视图,但只要UI线程可以自由处理消息,它就会这样做.最终,getView()将为每个项目调用.

Q2.notifyDataSetChanged()和UI线程之间有什么联系?

基本上,不允许从后台线程修改适配器的内容.notifyDataSetChanged()只是通知AdapterView它的数据已经改变的方式,它应该重新绘制.

Q3.有没有可以在工作线程上调用notifyDataSetChanged()的方法?

实际上,有几个.您可以使用Handler,AsyncTask.onPostExecute(),Activity.runOnUiThread()View.post().