我有一个AsyncTask,它在onPostExecute事件中刷新我的listView,并在doInBackground事件中检索一些数据。问题是我的AsyncTask在onScroll事件中被多次执行。我怎么能阻止它呢? 顺便说一句,我正在尝试在我的应用程序中创建一个Inifinite Scroll。也许我做错了什么? 这是我的onScroll活动:
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
previousTotal = totalItemCount;
try {
itemNews = listAdapter.getData();
}catch (Exception e){
System.out.println("itemNews is empty");
}
if(totalItemCount > 2) {
artId = itemNews.get(firstVisibleItem).articleId;
}
if(firstVisibleItem > ((previousTotal)/2))
{
UpdateListAsyncTask updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
这是我的AsyncTask:
public class UpdateListAsyncTask extends AsyncTask<Void, Void, Void> {
public int currentArticleId;
public Activity mActivity;
RemoteData remoteData;
public ListAdapterRegular listAdapter;
UpdateListAsyncTask(int currentArticleId, Activity activity, ListAdapterRegular listAdapterRegular)
{
this.mActivity = activity;
this.currentArticleId = currentArticleId;
this.listAdapter = listAdapterRegular;
}
@Override
protected void onPreExecute()
{
remoteData = new RemoteData(mActivity, "News");
}
@Override
protected Void doInBackground(Void... params) {
try{
remoteData.writeServerData("&from=" + currentArticleId);
System.out.println("DoInBackground writeServerData");
}catch (Exception e)
{
e.printStackTrace();
System.out.println("UpdateListAsyncTask: doInBackground exception!");
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
List<News> dataList = Select.from(News.class).orderBy("date DESC").list();
System.out.println("onPostExecuteInitiated");
listAdapter.clear();
listAdapter.addAll(dataList);
listAdapter.notifyDataSetChanged();
}
}
非常感谢任何帮助和想法! 更新: 我不得不重做我的代码,但它值得。我已根据链接https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews
完成了答案 0 :(得分:1)
我会用这样的东西
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
previousTotal = totalItemCount;
try {
itemNews = listAdapter.getData();
}catch (Exception e){
System.out.println("itemNews is empty");
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) { this.loading = true; }
}
if(totalItemCount > 2) {
artId = itemNews.get(firstVisibleItem).articleId;
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if(loading && totalItemCount > previousTotalItemCount) {
loading = false;
previousTotalItemCount = totalItemCount;
}
if(!loading && firstVisibleItem > ((previousTotal)/2))
{
loading = true;
UpdateListAsyncTask updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
}
PS当我实现无限滚动时,我以此为例https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews
答案 1 :(得分:1)
您的方法可以有其他改进,但如果没有任何改进,如果您想要的是多个异步任务无法运行,为什么不试试呢?
更改强>
if(firstVisibleItem > ((previousTotal)/2))
{
UpdateListAsyncTask updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
要强>
if(firstVisibleItem > ((previousTotal)/2))
{
if(mUpdateListAsyncTask != null && (mUpdateListAsyncTask.getStatus == AsyncTask.Status.RUNNING|| mUpdateListAsyncTask.getStatus ==AsyncTask.Status.PENDING)) {
return;
} else {
mUpdateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
}
基本上,只需跳过创建新的异步任务并在状态为RUNNING或PENDING时运行它。应该工作。
答案 2 :(得分:0)
您可能希望执行上一个任务,因此我会将UpdateListAsyncTask updateListAsyncTask
作为属性。
现在改变这个:
if(firstVisibleItem > ((previousTotal)/2))
{
UpdateListAsyncTask updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
到此:
if(firstVisibleItem > ((previousTotal)/2))
{
try{
updateListAsyncTask.cancel(true);
}catch(Exception ex){}
updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
updateListAsyncTask.execute();
}
答案 3 :(得分:0)
private UpdateListAsyncTask updateListAsyncTask = null;
...
if(firstVisibleItem > ((previousTotal)/2))
{
//Create just if not exist or if it's finished
if (updateListAsyncTask == null || updateListAsyncTask.getStatus() == Status.FINISHED) {
updateListAsyncTask = new UpdateListAsyncTask(artId, mActivity, listAdapter);
}
//Start only if it's not already running
if (updateListAsyncTask.getStatus() == Status.PENDING) {
updateListAsyncTask.execute();
}
}