取消AsyncTask的问题

时间:2017-02-28 13:07:55

标签: android android-asynctask

我在没有找到正确解决方案的情况下完成了很多关于这个主题的阅读。

我有一个程序可以进行网络发现(使用ping)。我不明白你是如何停止异步任务的。我正在做一个task.cancelled(true),但似乎什么也没做。最重要的是,我做了一段时间()来检查任务是否被取消,并立即返回。

序列:启动(正常工作)我等待5-10个IP地址,然后单击按钮停止。然后我点击start但发现任务没有执行。

我们真的可以停止异步任务吗?怎么样?这有什么延迟?

修改

我输了。 Stackoverflow中的所有Q都表明取消(true)需要来自任务。

  1. 我有一个例子,我在doinbackground中调用了cancel(true),但它没有触发onCancelled

  2. 大多数情况下(至少是循环)停止必须超出任务范围。下面我的例子只是在循环计数器上播放。这很有效。

  3. Q Ideal way to cancel an executing AsyncTask

    中有一个来自wrygiel的中间评论

    有一个真实的例子会很棒。

    这是我的代码修改但是onCancelled没有用,所以我在循环计数器上玩。

    public class MainActivity extends AppCompatActivity {
        TextView text;
        Discover discover;
        int count;
        private boolean running = true;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button start = (Button) findViewById(R.id.start);
            Button stop = (Button) findViewById(R.id.stop);
            text = (TextView) findViewById(R.id.txt);
    
            start.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    discover = new Discover();
                    discover.execute();
                }
            });
    
            stop.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
             //       if(discover != null)
             //           discover.cancel(true);
                    count = 255;
                }
            });
        }
    
        private class Discover extends AsyncTask<Object, String, Void> {
    
            @Override
            protected Void doInBackground(Object... params) {
                String ip;
                Ping ping = new Ping();
    
                for(count=1;count<255;count++) {
                    if(!running) {
                        count = 255;
                        Log.i("Discover", "task terminated");
                    }
                    ip = "192.168.1." + count;
                    if (!ping.pong(ip))
                        publishProgress(ip+" not alive ");
                    else
                        publishProgress(ip+" is alive");
                }
                return null;
            }
    
            @Override
            protected void onPreExecute() {
                text.setText("Start search...");
                super.onPreExecute();
            }
    
            @Override
            protected void onProgressUpdate(String... values) {
                super.onProgressUpdate(values);
                text.setText(values[0]);
            }
    
            @Override
            protected void onPostExecute(Void result) {
                text.setText("Task finished");
                super.onPostExecute(result);
            }
    
            @Override
            protected void onCancelled() {
                running = false;
                super.onCancelled();
            }
    
        }
    }
    

2 个答案:

答案 0 :(得分:1)

你无法以这种方式停止asyncTask。您可以随时使用discover.cancel(true);,但必须手动停止 - 请在discover.isCancelled()方法中查看值doInBackground。否则AsyncTask将调用整个doInBackground方法,但不会通过onPostExecute

答案 1 :(得分:0)

Asynctask具有内置onCancelled()方法,如onPostExecute()

  @Override
    protected void onCancelled() {
        super.onCancelled();
    }

并且您需要定期检查asynctask的状态,在后台函数中,当您取消它时,onCancelled()方法将被调用而不是onPostExecute()