我正在学习如何取消asyncTask,因此下面的代码没有用处。
我试图调用asyncTask并执行它然后取消并执行它。
MyAsyncTask asyncTask = new MyAsyncTask();
Log.i("cancel","cancel 1");
asyncTask.execute();
Log.i("cancel","cancel 2");
asyncTask.onCancelled();
Log.i("cancel","cancel 3");
asyncTask.execute();
Log.i("cancel","cancel done");
“取消1”和“取消2”在logcat上显示正确执行,但当“取消3”尝试执行时抛出ActivityThread.performLaunchActivity错误。 (在logcat上没有显示取消3)我的asyncTask代码有什么问题吗?
private class MyAsyncTask extends AsyncTask<String,Integer,Void>{
private ArrayList<Map<String, String>> list;
private ProgressBar progressBar;
@Override
protected Void doInBackground(String... arg0) {
progressBar = (ProgressBar)findViewById(R.id.year_expense_progressbar);
progressBar.setVisibility(View.VISIBLE);
getListView().setVisibility(View.GONE);
textView.setVisibility(View.GONE);
list = new ArrayList<Map<String, String>>();
String time = "";
String category = "";
String expense = "";
String day = "";
String month = "";
totalExpense = 0;
Cursor c = SQLLiteAdapter.fetchAllItems();
while(c.moveToNext() != false){
if(isCancelled()){
Log.e("cancel","cancel inside background");
break;
}
// if there is nothing is input, don't execute verifyLevel
if(tokenizedResult.isEmpty()) break;
category = c.getString(c.getColumnIndex(SQLLiteAdapter.col_category));
expense = c.getString(c.getColumnIndex(SQLLiteAdapter.col_price));
time = c.getString(c.getColumnIndex(SQLLiteAdapter.col_time));
day = c.getString(c.getColumnIndex(SQLLiteAdapter.col_day));
month = c.getString(c.getColumnIndex(SQLLiteAdapter.col_month));
VerifyLevel a = new VerifyLevel(tokenizedResult,category,expense,time,day,month);
if(!a.isEmpty()){
list.add(a.addToList());
}
totalExpense += a.totalExpense;
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
progressBar.setVisibility(View.GONE);
getListView().setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
fillData(list);
textView.setText("Total Expense is "+convertNumeric(totalExpense));
Log.i("yearExpense","buildList is finished");
}
@Override
protected void onCancelled(){
super.onCancelled();
list.clear();
progressBar.setVisibility(View.GONE);
totalExpense = 0;
Log.i("yearEx","Cancel asyncTask");
Toast.makeText(getApplicationContext(), "cancelled", Toast.LENGTH_SHORT).show();
}
}
答案 0 :(得分:13)
我的方法略有不同,也许有点冗长。但它一直没有任何问题。
这段代码放在doInBackground()
中。如果其中包含for... loop
,请使用break;
语句。如果您不使用for.... loop
,请将其删除。
// CHECK IF THE USER HAS CANCELLED THE TASK
if (isCancelled()) {
cancelTask = true; // (OPTIONAL) THIS IS AN ADDITIONAL CHECK I HAVE USED. THINK OF IT AS A FAIL SAFE.
break; // REMOVE IF NOT USED IN A FOR LOOP
}
您已宣布Asynctask
:MyAsyncTask asyncTask = new MyAsyncTask();
。除此之外,还创建两个boolean
实例。打电话给他们,例如:
boolean blMyAsyncTask;
boolean cancelTask;
现在,在onPreExecute()
中,切换blMyAsyncTask实例的状态:
blMyAsyncTask = true;
在onPostExecute()
:
blMyAsyncTask = false;
并且,在同一onPostExecute()
中,我还在检查cancelTask boolean
的状态后执行余数函数。例如:
if (cancelTask == false) {
// THE NORMAL CODE YOU HAVE IN YOUR onPostExecute()
}
最后,在onDestroy()
中(我使用了这个,但我怀疑onPause()
也可以正常工作。从来没有在onPause()
诚实地完成它),检查状态boolean blMyAsyncTask
if (blMyAsyncTask== true) {
asyncTask.cancel(true);
}
正如我在开始时说的那样,它很长,甚至可能很复杂,但它从未失败过。如果你愿意,我也会把它想象成一个模块化。如果我在Asycntasks
添加了更多Activity
,我可以在onDestroy()
添加另一项检查。
答案 1 :(得分:3)
您不应直接致电asyncTask.onCancelled();
。您可以致电cancel(true)
并在doInBackground()
内查看isCancelled()
。
答案 2 :(得分:0)
您可以使用
asynctask.cancel(true);
或
asyncTask.wait();
如果执行此任务的线程应该被中断,则“true”;否则,允许正在进行的任务完成
答案 3 :(得分:-1)
要取消AsyncTask,请拨打以下行。
asyncTask.cancel();
onCancelled()是一种覆盖方法,在调用cancel时执行。