在我的应用中。有一个ListView并将数据填充到列表视图中,抛出使用ArrayList的ArrayAdapter。
我想通过AsyncTask将listview更新为doInBackground方法,所以我使用onProgressUpdate方法。这里我在适配器上做notifyDataSetChanged。
但是当编译器尝试执行代码aAdapter.notifyDataSetChanged();
时
那就扔错了。
代码: -
private class StatisticsTask extends AsyncTask<String, Integer, Long> {
@Override
protected Long doInBackground(String... params) {
int count = 0;
while(count < dummyClass.getStatisticsClassList().size()){
try {
Thread.sleep(1000);
onProgressUpdate(count);
count++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == dummyClass.getStatisticsClassList().size()) {
statisticsTask.cancel(true);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
updateProgress(values[0]);
}
}
public void updateProgress(Integer... values) {
aListStatisticsClass.add(dummyClass.getStatisticsClassList().get(values[0]));
aAdapterStatisticsClass.notifyDataSetChanged();
}
错误: -
03-04 15:33:49.757: E/AndroidRuntime(1778): FATAL EXCEPTION: AsyncTask #1
03-04 15:33:49.757: E/AndroidRuntime(1778): Process: com.example.elevateapp, PID: 1778
03-04 15:33:49.757: E/AndroidRuntime(1778): java.lang.RuntimeException: An error occured while executing doInBackground()
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.os.AsyncTask$3.done(AsyncTask.java:300)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.lang.Thread.run(Thread.java:841)
03-04 15:33:49.757: E/AndroidRuntime(1778): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6024)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:820)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.view.View.requestLayout(View.java:16431)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.AbsListView.requestLayout(AbsListView.java:1916)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:814)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6287)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
03-04 15:33:49.757: E/AndroidRuntime(1778): at com.example.elevateapp.MainActivity.updateProgress(MainActivity.java:94)
03-04 15:33:49.757: E/AndroidRuntime(1778): at com.example.elevateapp.MainActivity$StatisticsTask.onProgressUpdate(MainActivity.java:81)
03-04 15:33:49.757: E/AndroidRuntime(1778): at com.example.elevateapp.MainActivity$StatisticsTask.doInBackground(MainActivity.java:67)
03-04 15:33:49.757: E/AndroidRuntime(1778): at com.example.elevateapp.MainActivity$StatisticsTask.doInBackground(MainActivity.java:1)
03-04 15:33:49.757: E/AndroidRuntime(1778): at android.os.AsyncTask$2.call(AsyncTask.java:288)
03-04 15:33:49.757: E/AndroidRuntime(1778): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-04 15:33:49.757: E/AndroidRuntime(1778): ... 4 more
答案 0 :(得分:1)
notifyDataSetChanged()
以及所有其他与UI相关的方法必须在主(UI)线程上执行。
AsyncTask
创建并运行自己的线程,以便它消除主要的压力,让应用程序保持用户响应。
根据documentation,onProgressUpdate(...)
方法在UI线程上运行,但是您应该调用publishProgress(...)
方法并直接从一个onProgressUpdate(...)
调用导致错误的非UI线程。
要解决此问题,只需将onProgressUpdate(count)
替换为publishProgress(count)
即可。干杯:D