AsyncTask的取消不工作 [英] AsyncTask Cancel is not working

查看:244
本文介绍了AsyncTask的取消不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习如何取消的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

 如果(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆