2014-05-05 69 views
0

加载我有一个正常的列表视图/ listadapter,我从网络上使用的AsyncTask加载大量数据,如何快速更新的Android的ListView。大约需要5秒钟才能完全下载和解析所有数据。数据从网络

而不是让列表视图空5秒,而我处理的数据,我想作为数据进行处理,使用户可以看到,并通过列表项滚动,因为他们已经准备好更新。处理每个物品需要大约20-50ms,并准备好显示。

可有人请给我拿我如何能做到这一点的一些想法。

我试过这段代码,每500ms只刷新一次。我从当一个新项目已完成正在处理的AsyncTask调用onNewItemReady()每20到50毫秒:

public void onNewItemReady(Object item) { 
    mData.add(item); 

    long diff = SystemClock.elapsedRealtime()-mLastRefresh; 
    if (diff > 500) { 
     mAdapter.setData(mData); 
     mAdapter.notifyDataSetChanged(); 
     mLastRefresh = SystemClock.elapsedRealtime(); 
    } 
} 

,但如果我滚动所有的数据加载之前的列表视图,我收到以下错误:

> 05-04 19:22:59.638: E/AndroidRuntime(24349): 
> java.lang.IllegalStateException: The content of the adapter has 
> changed but ListView did not receive a notification. Make sure the 
> content of your adapter is not modified from a background thread, but 
> only from the UI thread. Make sure your adapter calls 
> notifyDataSetChanged() when its content changes. [in 
> ListView(16908298, class android.widget.ListView) with Adapter(class 
> MyAdapter)] 

谢谢!

编辑:我不刷新适配器从后台线程。 onNewItemReady()正在从AsyncTask的onProgressPublished中调用。

+0

而不是'mAdapter.setData(MDATA);',你可能会考虑做一些像'mAdapter。addData(newItem);' –

+0

此外,你是从UI线程还是后台线程调用'onNewItemReady'? –

+0

从UI线程。 – Nek

回答

0

我使用了“无休止的适配器”,当用户滚动至底部显示在列表视图我的底部增加了“装载”的看法。我使用了Google I/O 2013应用中使用的代码。显然这个代码是造成这个问题。我已经删除它,并用一个更简单的footerview替换它,问题已消失。

这是我用我的适配器代码:

@Override 
public int getCount() { 
    if (mData != null) { 
     return mData.size() + (
       ((mDataTask.isLoading())  // we are already loading 
      || mDataTask.hasMoreResults() // or there are more results 
      || mDataTask.isErrored())  // or there's an error 
      ? 1 : 0); 
     } 
    return 0; 
} 

,而不是这个代码,我只需添加一个footerview当我开始加载,并onPostExecute完成后我将其删除。

0

由于logcat消息表示您正试图从后台线程(可能是AsyncTask)刷新列表视图(可能是AsyncTask),所以您只需在完成AsyncTask的doInbackground()执行后,应刷新asynctask的列表视图。

为了避免用户交互,而你的下载过程是怎么回事,你应该表现出进步onPreexcecute()对话框。

所以您的AsyncTask应该是这样的:

class YourAsyncTask extends AsyncTask{ 
ProgressDialog pd; 
onPreExecute(){ 
// show progress dialog here.. 
} 

doInBackground(){ 
// perform network operation here and collect collect data 
} 

onPostExecute(){ 
// dismiss dialog box. 
// refresh listview 
} 

} 

注意这仅仅是你的代码的蓝图,为正确的语法参考this

替代 你也说你被加载为大量的数据,它需要近5秒(这是很多时间),它是推荐使用Pull-to-refresh,因为它会load data on demand。你可以谷歌它和很多东西都可以在那里。

+0

感谢您的评论。我正在使用适当的asynctask工作流程。我不想显示进度对话框,因为我希望用户能够滚动浏览当前加载的项目,而不是等待所有数据下载和处理。 – Nek

+0

然后,你应该看看'懒惰加载'在列表视图。这可能会帮助你。 – guptakvgaurav