【问题标题】:Issue with cancelling an AsyncTask取消 AsyncTask 的问题
【发布时间】:2017-03-01 00:03:03
【问题描述】:

我在这个主题上做了很多阅读,但没有找到正确的解决方案。

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

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

我们真的可以停止异步任务吗?如何?它的延迟是多少?

编辑

我迷路了。 Stackoverflow 中的所有 Q 都表明 cancel(true) 需要来自任务。

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

  2. 大多数情况下(至少对于循环),停止必须在任务之外。我下面的示例只是在循环计数器上播放。这行得通。

一个有趣的评论来自 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();
        }

    }
}

【问题讨论】:

标签: android android-asynctask


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    您需要定期检查异步任务的状态,在后台功能中,当您取消它时,将调用onCancelled()方法而不是onPostExecute()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      相关资源
      最近更新 更多