Android 从异步任务更新ListView适配器
我拥有的是一个Android 从异步任务更新ListView适配器,android,multithreading,listview,adapter,Android,Multithreading,Listview,Adapter,我拥有的是一个AsyncTask,,它在ListView到达屏幕底部的项目时就开始了,在AsyncTask中,它向ListView添加了新项目。 代码如下: @Override protected void onPostExecute(final List<ItemDailyRecord> records) { super.onPostExecute(records); ((ActivityHome)context).runOnUiTh
AsyncTask,
,它在ListView
到达屏幕底部的项目时就开始了,在AsyncTask
中,它向ListView添加了新项目。
代码如下:
@Override
protected void onPostExecute(final List<ItemDailyRecord> records) {
super.onPostExecute(records);
((ActivityHome)context).runOnUiThread(new Runnable() {
public void run() {
for (ItemDailyRecord p : records) {
adapter.add(p);
}
adapter.notifyDataSetChanged();
}
});
}
@Override
protected List<ItemDailyRecord> doInBackground(Void... voids) {
DbAdapterDailyRecord db = new DbAdapterDailyRecord(context);
List<ItemDailyRecord> list = db.getRecordsFromTo(offset, count);
return list;
}
错误消息是(如果我滚动listview太快:)
原因:android.view.ViewRootImpl$CalledFromErrorThreadException:
只有创建视图层次结构的原始线程才能接触其
观点
有什么办法解决这个问题吗?在UI线程上执行
onPostExecute()
方法,因此您应该用这个方法直接更新UI;无需生成新的Runnable
对象。您不应该从适配器的getView执行异步任务。相反,您应该尝试使用ListView的getLastVisiblePosition()从列表所在的活动/片段执行此操作
像这样-->
在异步任务中,将额外数据附加到dataset,然后在适配器上调用notifyDataSetChanged()。
onPostExecute()
已经在UI线程中运行。runOnUiThread()
调用无效。显示您在doInBackground中使用的代码,但如果我删除它,错误消息也会出现:(另外,您是否应该将该项添加到引用该适配器而不是适配器本身的列表中?我用“doInBackground”更新了我的帖子方法。但即使我直接更新UI,我也会遇到:只有创建视图层次结构的原始线程才能接触其视图。您的ListView
适配器的类型是什么?公共类AdapterHistoryList扩展ArrayAdapter可能与我使用的片段相关,因此UI线程上没有正确调用。因为在我的代码中在一个活动“ActivityHome”中,我动态加载了一个片段“MyFragment extends SherlockFragment”。在这个“MyFragment”中,我有listview、adapter等。我不清楚这是否是问题的根源。如果在调试器中运行它,并在getView()
和onPostExecute()中设置断点
,您应该能够看到哪个线程正在执行这些方法。它应该是UI线程,它将在Eclipse调试窗口中标记为
。如果不是,请查看您是否可以跟踪(可能通过堆栈跟踪)生成此其他线程的原因。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(position == getCount() - 1 && hasMoreItems){
HistoryLoaderTask t = new HistoryLoaderTask(position + 1, pageSize, getContext(),this);
t.execute();
footer.setText("Loading . . .");
}
if(list.getLastVisiblePosition() == (dataSet.size() - 1)) {
// last item displayed
.... change the text off footer and execute async task
}