java - AsyncTask onCancelled(Object) 在 asyncTask.cancel(true) 之后从未调用过;

标签 java android multithreading android-studio android-asynctask

如文档所述,onCancelled(Object) 应在以下时间之后调用:

cancel(boolean) 被调用并且 doInBackground(Object[]) 已完成。

在我的 AsyncTask 中,我调用了 this.cancel(true); 但从未调用 onCancelled(Object) 方法。

此处仅贴出相关代码。

MainActivity.java:

 AsyncTask.Status asyncTaskStatus = new GetHtmlDocument(urlString).execute().getStatus();

异步任务:

private class GetHtmlDocument extends AsyncTask<String,Void,HtmlPage>
    {
        private String url;

        /**
         * Constructor.
         *
         * @param url Url to parse from in the web.
         */
        public GetHtmlDocument(String url)
        {
            this.url = url;
        }

        @Override
        protected void onPreExecute()
        {
            Log.d(MainActivity.ASYNC_TASK_TAG, "onPreExecute() called");
        }

        @Override
        protected HtmlPage doInBackground(String... params)
        {
            //android.os.Debug.waitForDebugger();
            Log.d(MainActivity.ASYNC_TASK_TAG, "doInBackground() called");

            if (this.isCancelled())
            {
                return null;
            }
            else
            {


                HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

                return htmlPage;
            }
        }

        /**
         * Runs on the UI thread after doInBackground().
         * The specified result is the value returned by doInBackground().
         * This method won't be invoked if the asynchronous task was cancelled.
         *
         * @param htmlPage
         */
        @Override
        protected void onPostExecute(HtmlPage htmlPage)
        {
            Log.d(MainActivity.ASYNC_TASK_TAG, "onPostExecute() called");

            if (htmlPage.getHtmlDocument() != null)
            {
                this.cancel(true);
            }

            setHtmlPage(htmlPage);
        }

        /**
         * 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.)
         *
         * @param htmlPage
         *
         */
        @Override
        protected void onCancelled(HtmlPage htmlPage)
        {
            Log.d(MainActivity.ASYNC_TASK_TAG, "onCancelled() called");
        }


    }

我调试了应用程序,我确定 this.cancel(true);AsyncTask onPostExecute() 方法中被调用.

最佳答案

这只是因为您在 AsyncTask 完成其工作后调用了 this.cancel(true)!

意思是,当 AsyncTask 在 doInBackground 中完成它的工作时,您可以取消它,并且在它的状态为“完成”之后

来自文档,

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.)

很明显,onCancelled 方法是在 AsyncTask 执行任务时调用的,在 doInBackground 完成之前,onCancelled(Object) 显然意味着在取消事件时调用 onPostExecute 的“INSTEAD”。 cancel(true)方法旨在“中断”AsyncTask 的操作。

还有,我想知道你为什么要取消任务?您可以简单地检查结果是否为 null 并仅在其不为 null 时才执行 onPostExecute,如下所示:

@Override
protected void onPostExecute(HtmlPage htmlPage)
{
    if (htmlPage.getHtmlDocument() != null){
       Log.d(MainActivity.ASYNC_TASK_TAG, "onPostExecute() called");
       setHtmlPage(htmlPage);
    }
}

@Override
protected void onPostExecute(HtmlPage htmlPage)
{
    Log.d(MainActivity.ASYNC_TASK_TAG, "onPostExecute() called");
    if (htmlPage.getHtmlDocument() != null){
       return;
    }

    setHtmlPage(htmlPage);
}

关于java - AsyncTask onCancelled(Object) 在 asyncTask.cancel(true) 之后从未调用过;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36528668/

相关文章:

java - 与延迟加载一对一关系的 n+1 问题

android - 如何检查 autoCompleteTextView 中的下拉状态(显示或隐藏)?

java - 如何在Android应用程序中使用ExecutorService关闭

asp.net - 在ASP.NET MVC 5 Controller 方法中调试多个线程

java - 从字符串创建对象并在同步块(synchronized block)中用作监视器

java - 为什么我可以实例化一个静态内部类?

java - 通过 scala.sys.process API 在 spark-scala 中执行外部命令 s3-dist-cp

javascript - Cordova 为 Android 构建错误所以我无法构建我的解决方案

java - 如何从适配器类处理/扩充多个 recycleview Activity

使用 Semaphore 运行时出现 java.util.NoSuchElementException