无法在Android的取消异步任务 [英] Can't cancel Async task in android

查看:90
本文介绍了无法在Android的取消异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要取消我的asyncthread。在我的应用我在做一些沉重的计算,我想给用户取消计算(然后重试)的能力。我读的论坛,你不能只是阻止它是什么做的任务,你需要检查的任务isCancelled =真在你DoinBackground code。但是,这并不为我工作。

任务本身是伟大的工作,它输出正确的数据,如果我阔叶它结束本身。

在我的应用程序第一次我称之为功能naredi_pdf_start(视图),则当任务运行时,如果我叫close_pdf1(视图),它给了我一个错误。(我改变看法和应用程序无法找到我的pdf_text1的TextView调用publishProgress-空指针异常时)。我真的不知道如何使用task.cancel(true)方法。(在我的情况:start_pdf.cancel(真)))

下面是我的code:

 字符串progress_pdf;
naredi_pdf start_pdf;

公共无效naredi_pdf_start(查看视图){
    start_pdf =新naredi_pdf();
    start_pdf.execute();
}

公共无效close_pdf1(查看视图){

    如果(start_pdf!= NULL){
        Log.v(非空,不为空);

        start_pdf.cancel(真正的);
        的setContentView(R.layout.other_view); //这是
                                             //我没有TextView的pdf_text1
    }
}

私有类naredi_pdf扩展的AsyncTask<太虚,字符串,太虚> {

    保护无效doInBackground(虚空...... ignoredParams){
        progress_pdf =计算统计数据;

        //编码不少

        的for(int i = 0;我和小于1;我++){
            如果(isCancelled()){
                打破;
            }
            其他 {
                publishProgress(计算团队统计);
            }
        }

        //编码更多

        的for(int i = 0;我和小于1;我++){
            如果(isCancelled()){
                打破;
            }
            其他 {
                publishProgress(计算玩家的BIO);
            }
        }

        //编码更多

        的for(int i = 0;我和小于1;我++){
            如果(isCancelled()){
                打破;
            }
        其他 {
                publishProgress(计算球员的个人表现);
            }
        }

        返回null;
    }

    保护无效onPostExecute(空数组){
        //保存到数据库
    }

    保护无效onProgressUpdate(字符串...值){
        progress_pdf =值[0] +\ N+ progress_pdf;

        如果(isCancelled()){

        }
        其他 {
            TextView的pdf_text1 =(TextView中)findViewById(R.id.pdf_text1);
            pdf_text1.setText(progress_pdf);
            //对话框(视图);
        }
    }
}
 

解决方案

您的问题不在于你无法取消的AsyncTask 。你可能会得到 NullPointerException异常,因为您的来电的setContentView()经过前 AsyncTask.cancel( )已成功。 A onProgressUpdate()被调用,却发现布局现在已经改变,也没有查看 ID = R.id.pdf_text1

从上 AsyncTask的。

  

一个任务可以在任何时候通过调用取消(布尔)取消。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,onCancelled(对象),而不是onPostExecute(对象)将doInBackground之后被调用(对象[])返回。为了确保任务是尽可能快地取消了,你应该总是定期从doInBackground检查isCancelled(返回值)(对象[]),如果可能的话(在例如一个循环。)

由于 onCancelled()运行在UI线程上,和你确信没有后续调用 onProgressUpdate()将occure,它是一个伟大的地方叫的setContentView()

覆盖 onCancelled()在你的AsyncTask

 私有类naredi_pdf扩展的AsyncTask<太虚,字符串,太虚> {

    保护无效doInBackground(虚空...... ignoredParams){//你的code HERE}
    保护无效onPostExecute(空数组){//你的code HERE}
    保护无效onProgressUpdate(字符串...值){//你的code HERE}

    //添加此
    @覆盖
    保护无效onCancelled(){
        //不要叫super.onCancelled()!

        //设置新的布局
        的setContentView(R.id.other_layout);
    }
}
 

修改 close_pdf1()

 公共无效close_pdf1(查看视图){
    如果(start_pdf!= NULL){
        Log.v(非空,不为空);

        start_pdf.cancel(真正的);
    }
}
 

和你应该有一个的AsyncTask 取消时自动改变你的布局。希望你应该不会遇到任何 NullPointerException异常无论是。没有尝试过的code,但:)

修改

如果你觉得花哨,按照Rezooms建议使用返回

 的for(int i = 0;我和小于1;我++){
    如果(isCancelled()){
        返回null;
    }
    。
    。
    。
}
 

I need to cancel my asyncthread . In my application I am doing some heavy calculations, and I want to give user ability to cancel calculations(and then retry). I read on forums, that you can't just stop task from what is it doing, and that you need to check if task isCancelled=true inside your DoinBackground code. But that doesn't work for me.

Task itself is working great and it outputs correct data if I leaved it to end on itself.

In my App first I call function naredi_pdf_start(view), then when the task is running, if I call close_pdf1(view), it gives me an error.(I am changing views and app can't find my pdf_text1 Textview when calling publishProgress- null pointer exception). I really dont know how to use task.cancel(true) method (in my case: start_pdf.cancel(true))).

Here is my code:

String progress_pdf;
naredi_pdf start_pdf;

public void naredi_pdf_start(View view) {
    start_pdf=new naredi_pdf();
    start_pdf.execute();
}

public void close_pdf1(View view) {

    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
        setContentView(R.layout.other_view); //This is where 
                                             //I don't have TextView pdf_text1
    }
}

private class naredi_pdf extends AsyncTask<Void, String, Void> {

    protected Void doInBackground( Void... ignoredParams ) {
        progress_pdf="Calculating Statistical Data";

        //A LOT OF CODING

        for(int i = 0; i < 1; i++) {
            if(isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating team statistics");  
            }
        }

        //MORE OF CODING              

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
            else {
                publishProgress("Calculating player's BIO");  
            }
        }

        //MORE OF CODING       

        for (int i = 0; i < 1; i++) {
            if (isCancelled()) {
                break;
            }
        else {
                publishProgress("Calculating player's individual performance");
            }
        }

        return null; 
    }

    protected void onPostExecute( Void array ) {
        //saving to database
    }

    protected void onProgressUpdate(String... values) {
        progress_pdf=values[0]+"\n"+progress_pdf;

        if (isCancelled())  {

        }
        else {
            TextView pdf_text1 = (TextView) findViewById (R.id.pdf_text1);
            pdf_text1.setText(progress_pdf);
            // dialog(view);
        }
    }
}

解决方案

Your problem is not that you can't cancel the AsyncTask. You probably get NullPointerException because your call to setContentView() goes through before AsyncTask.cancel() has been successful. A onProgressUpdate() gets called, only to find that the layout is now changed and there is no Viewwith id=R.id.pdf_text1!

From documentation on AsyncTask.

A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

Since onCancelled() runs on the UI thread, and you are certain that no subsequent calls to onProgressUpdate() will occure, it's is a great place to call setContentView().

Override onCancelled() in you AsyncTask

private class naredi_pdf extends AsyncTask<Void, String, Void> {

    protected Void doInBackground( Void... ignoredParams ) { // YOUR CODE HERE}
    protected void onPostExecute( Void array ) { // YOUR CODE HERE}
    protected void onProgressUpdate(String... values) {// YOUR CODE HERE}

    // ADD THIS
    @Override
    protected void onCancelled() {
        // Do not call super.onCancelled()!

        // Set the new layout
        setContentView(R.id.other_layout);
    }
}

Change close_pdf1()

public void close_pdf1(View view) {
    if(start_pdf!=null) {
        Log.v("not null","not null");

        start_pdf.cancel(true);
    }
}

And you should have an AsyncTask that automatically changes your layout when cancelled. Hopefully you should not encounter any NullPointerException either. Haven't tried the code though :)

Edit

If you feel fancy, follow Rezooms advice on using return.

for(int i = 0; i < 1; i++) {
    if(isCancelled()) {
        return null;
    }
    .
    .
    .
}

这篇关于无法在Android的取消异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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