AsyncTask的取消不工作 [英] AsyncTask Cancel is not working
问题描述
我学习如何取消的AsyncTask所以下面的code无用途。
我试着叫AsyncTask的并执行它,然后取消它,执行它。
MyAsyncTask的AsyncTask =新MyAsyncTask();
Log.i(取消,取消1);
asyncTask.execute();
Log.i(取消,取消2);
asyncTask.onCancelled();
Log.i(取消,取消3);
asyncTask.execute();
Log.i(取消,取消DONE);
取消1和取消2作为logcat的显示,但ActivityThread.performLaunchActivity引发错误时,取消3试图执行被精细地执行。
(取消3 logcat中未显示),任何问题我的AsyncTask code?
私有类MyAsyncTask扩展的AsyncTask<字符串,整数,太虚> { 私人的ArrayList<地图<字符串,字符串>>清单;
私人进度进度;
@覆盖
保护无效doInBackground(字符串...为arg0){ 进度=(进度)findViewById(R.id.year_expense_progressbar);
progressBar.setVisibility(View.VISIBLE);
。getListView()setVisibility(View.GONE);
textView.setVisibility(View.GONE); 名单=新的ArrayList<地图<字符串,字符串>>(); 字符串时间=;
串类=;
字符串费用=;
字符串日=;
串月=;
totalExpense = 0;
光标C = SQLLiteAdapter.fetchAllItems(); 而(c.moveToNext()!= FALSE){ 如果(isCancelled()){
Log.e(取消,取消里面的背景);
打破;
}
//如果不输入,不执行verifyLevel
如果(tokenizedResult.isEmpty())破;
类别= c.getString(c.getColumnIndex(SQLLiteAdapter.col_category));
费用= c.getString(c.getColumnIndex(SQLLiteAdapter.col_price));
时间= c.getString(c.getColumnIndex(SQLLiteAdapter.col_time));
天= c.getString(c.getColumnIndex(SQLLiteAdapter.col_day));
一个月= c.getString(c.getColumnIndex(SQLLiteAdapter.col_month));
VerifyLevel一个=新VerifyLevel(tokenizedResult,类别,费用,时间,日,月);
如果(!a.isEmpty()){
list.add(a.addToList());
} totalExpense + = a.totalExpense;
} 返回null;
} @覆盖
保护无效onPostExecute(虚空结果)
{
progressBar.setVisibility(View.GONE);
。getListView()setVisibility(View.VISIBLE);
textView.setVisibility(View.VISIBLE);
fillData(名单);
textView.setText(总费用是+ convertNumeric(totalExpense));
Log.i(yearExpense,buildList完成); } @覆盖
保护无效onCancelled(){
super.onCancelled();
list.clear();
progressBar.setVisibility(View.GONE);
totalExpense = 0;
Log.i(yearEx,取消的AsyncTask);
Toast.makeText(getApplicationContext(),取消,Toast.LENGTH_SHORT).show(); }
}
我的做法略有不同,也许,有点冗长。但它一直工作没有任何问题。
这件code的云在 doInBackground()
。如果你有一个的......在这循环
,然后使用打破;
语句。如果不使用的....循环
,将其删除。
//检查用户是否有已取消任务
如果(isCancelled()){
cancelTask = TRUE; //(可选)这是额外的检查,我都习惯了。 IT作为故障安全思考。
打破; //移除如果不使用在for循环
}
您已经有一个的AsyncTask
声明: MyAsyncTask的AsyncTask =新MyAsyncTask();
。伴随着的是,还可以创建布尔
的两个实例。打电话给他们,例如:
布尔blMyAsyncTask;
布尔cancelTask;
现在,在上preExecute()
,切换blMyAsyncTask实例的状态:
blMyAsyncTask = TRUE;
而在 onPostExecute()
:
blMyAsyncTask = FALSE;
和,在相同的 onPostExecute()
,我也做了其余功能检查 cancelTask布尔的状态之后,
。例如:
如果(cancelTask == FALSE){
// THE师范大学code你有你的onPostExecute()
}
最后,在的onDestroy()
(我用这个,但我怀疑的onPause()
可以工作也千万不要在的onPause()
在所有诚实),检查的状态布尔blMyAsyncTask
做到了p>
如果(blMyAsyncTask ==真){
asyncTask.cancel(真);
}
正如我在开始时说,这是漫长的,甚至可能是复杂的,但它从来没有失败过。我也认为这是一个小的模块的,如果你会的。如果我有更多的 Asycntasks
添加到的活动,我可以在
的onDestroy添加其他检查()
。
I am learning how to cancel asyncTask so there is no uses on the code below.
I tried to called the asyncTask and execute it then cancel it and execute it.
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");
"cancel 1" and "cancel 2" is executed finely as it shown on logcat but ActivityThread.performLaunchActivity error is thrown when "cancel 3" is trying to execute. (cancel 3 is not showing on logcat) Anything wrong with my asyncTask code?
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();
}
}
My approach is slightly different and perhaps, a little lengthy. But it has always worked without any issues.
This piece of code goes in the doInBackground()
. If you have a for... loop
in it, then use the break;
statement. If you do not use a for.... loop
, remove it.
// 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
}
You already have an Asynctask
declared: MyAsyncTask asyncTask = new MyAsyncTask();
. Along with that, also create two instances of boolean
. Call them, for example:
boolean blMyAsyncTask;
boolean cancelTask;
Now, in the onPreExecute()
, toggle the status of the blMyAsyncTask instance:
blMyAsyncTask = true;
And in the onPostExecute()
:
blMyAsyncTask = false;
And, in the same onPostExecute()
, I also do the remainder functions after checking the state of the cancelTask boolean
. For example:
if (cancelTask == false) {
// THE NORMAL CODE YOU HAVE IN YOUR onPostExecute()
}
Finally, in the onDestroy()
(I use this, but I suspect the onPause()
could work too. Never done it in the onPause()
in all honesty), check the status of the boolean blMyAsyncTask
if (blMyAsyncTask== true) {
asyncTask.cancel(true);
}
As I said at the start, it is lengthy, perhaps even complicated, but it has never failed. I also think of this as a little modular if you would. If I have more Asycntasks
added to the Activity
, I can add another check in the onDestroy()
.
这篇关于AsyncTask的取消不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!