我正在学习如何取消 asyncTask 所以下面的代码没有用处.
I am learning how to cancel asyncTask so there is no uses on the code below.
我尝试调用 asyncTask 并执行它,然后取消它并执行它.
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"和cancel 2"执行得很好,正如它在 logcat 上显示的那样,但是当cancel 3"尝试执行时会抛出 ActivityThread.performLaunchActivity 错误.(取消 3 未显示在 logcat 上)我的 asyncTask 代码有问题吗?
"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.
这段代码在 doInBackground() 中.如果其中有 for... 循环,请使用 break; 语句.如果您不使用 for.... 循环,请将其删除.
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 }您已经声明了一个 Asynctask:MyAsyncTask asyncTask = new MyAsyncTask();.除此之外,还要创建两个 boolean 实例.打电话给他们,例如:
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;现在,在 onPreExecute() 中,切换 blMyAsyncTask 实例的状态:
Now, in the onPreExecute(), toggle the status of the blMyAsyncTask instance:
blMyAsyncTask = true;在onPostExecute()中:
blMyAsyncTask = false;而且,在同一个onPostExecute()中,我还在检查cancelTask boolean的状态后执行余数函数.例如:
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() }最后,在 onDestroy()(我使用这个,但我怀疑 onPause() 也可以工作.从来没有在 onPause() 老实说),检查 boolean blMyAsyncTask
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); }正如我在开始时所说的,它很长,甚至可能很复杂,但它从未失败过.如果您愿意,我也认为这是一个小模块化.如果我有更多的 Asycntasks 添加到 Activity,我可以在 onDestroy() 中添加另一个检查.
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().
更多推荐
异步任务取消不起作用
发布评论