Android AsyncTask onPostExecute()从未被调用+;W/art:暂停所有线程所需时间:1.1ms

Android AsyncTask onPostExecute()从未被调用+;W/art:暂停所有线程所需时间:1.1ms,android,multithreading,asynchronous,android-asynctask,jsoup,Android,Multithreading,Asynchronous,Android Asynctask,Jsoup,我知道这方面有很多问题,但没有一个能帮到我 我得到了一个AsyncTask,它使用Jsoup处理一些HTML解析 我对应用程序进行了无数次调试(真的),在调用doInBackground()方法之后,我得到了想要发送到onPostExecute()方法的值,但问题是从未调用onPostExecute()方法 我想是一些简单的事情从我身上溜走了 只是相关代码 MainActivity.java: private HtmlPage htmlPage = new HtmlPage(); pr

我知道这方面有很多问题,但没有一个能帮到我

我得到了一个
AsyncTask
,它使用
Jsoup
处理一些
HTML
解析

我对应用程序进行了无数次调试(真的),在调用
doInBackground()
方法之后,我得到了想要发送到
onPostExecute()
方法的值,但问题是从未调用
onPostExecute()
方法

我想是一些简单的事情从我身上溜走了

只是相关代码

MainActivity.java:

private HtmlPage htmlPage = new HtmlPage();

    private static final String ASYNC_TASK_TAG = "AsyncTask";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting the HTML document from a background thread
        new GetHtmlDocument("someUrlString").execute();

        if (this.htmlPage.getHtmlDocument() != null)
        {
            new GetHtmlDocument("someUrlString").cancel(true);
        }

        while (this.htmlPage.getHtmlDocument() == null)
        {
            if (this.htmlPage.getHtmlDocument() != null)
            {
                new GetHtmlDocument("someUrlString").cancel(true);
            }
            else
            {
                new GetHtmlDocument("someUrlString").execute();
            }
        }
    }
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");

            // Get the HTML http://www.lyricsplanet.com/ document
            HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

            return 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");
        }
    }
public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }
public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}
   public Document getParsedDocument(String url)
    {
        try
        {
            return Jsoup.connect(url).get();
        }
        catch (IOException e) // On error
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null; // Failed to connect to the url
    }
异步任务内部类:

private HtmlPage htmlPage = new HtmlPage();

    private static final String ASYNC_TASK_TAG = "AsyncTask";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting the HTML document from a background thread
        new GetHtmlDocument("someUrlString").execute();

        if (this.htmlPage.getHtmlDocument() != null)
        {
            new GetHtmlDocument("someUrlString").cancel(true);
        }

        while (this.htmlPage.getHtmlDocument() == null)
        {
            if (this.htmlPage.getHtmlDocument() != null)
            {
                new GetHtmlDocument("someUrlString").cancel(true);
            }
            else
            {
                new GetHtmlDocument("someUrlString").execute();
            }
        }
    }
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");

            // Get the HTML http://www.lyricsplanet.com/ document
            HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

            return 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");
        }
    }
public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }
public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}
   public Document getParsedDocument(String url)
    {
        try
        {
            return Jsoup.connect(url).get();
        }
        catch (IOException e) // On error
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null; // Failed to connect to the url
    }
HtmlPage.java:

private HtmlPage htmlPage = new HtmlPage();

    private static final String ASYNC_TASK_TAG = "AsyncTask";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting the HTML document from a background thread
        new GetHtmlDocument("someUrlString").execute();

        if (this.htmlPage.getHtmlDocument() != null)
        {
            new GetHtmlDocument("someUrlString").cancel(true);
        }

        while (this.htmlPage.getHtmlDocument() == null)
        {
            if (this.htmlPage.getHtmlDocument() != null)
            {
                new GetHtmlDocument("someUrlString").cancel(true);
            }
            else
            {
                new GetHtmlDocument("someUrlString").execute();
            }
        }
    }
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");

            // Get the HTML http://www.lyricsplanet.com/ document
            HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

            return 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");
        }
    }
public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }
public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}
   public Document getParsedDocument(String url)
    {
        try
        {
            return Jsoup.connect(url).get();
        }
        catch (IOException e) // On error
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null; // Failed to connect to the url
    }
在doInBackground()中使用的方法:

private HtmlPage htmlPage = new HtmlPage();

    private static final String ASYNC_TASK_TAG = "AsyncTask";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting the HTML document from a background thread
        new GetHtmlDocument("someUrlString").execute();

        if (this.htmlPage.getHtmlDocument() != null)
        {
            new GetHtmlDocument("someUrlString").cancel(true);
        }

        while (this.htmlPage.getHtmlDocument() == null)
        {
            if (this.htmlPage.getHtmlDocument() != null)
            {
                new GetHtmlDocument("someUrlString").cancel(true);
            }
            else
            {
                new GetHtmlDocument("someUrlString").execute();
            }
        }
    }
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");

            // Get the HTML http://www.lyricsplanet.com/ document
            HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

            return 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");
        }
    }
public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }
public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}
   public Document getParsedDocument(String url)
    {
        try
        {
            return Jsoup.connect(url).get();
        }
        catch (IOException e) // On error
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null; // Failed to connect to the url
    }
我想问题在于主
线程
从来没有机会调用
onPostExecute()
方法,或者使用我的
AsyncTask
Generic
参数,或者我的
AsyncTask
类的实现

如有任何建议,我们将不胜感激

编辑:

private HtmlPage htmlPage = new HtmlPage();

    private static final String ASYNC_TASK_TAG = "AsyncTask";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting the HTML document from a background thread
        new GetHtmlDocument("someUrlString").execute();

        if (this.htmlPage.getHtmlDocument() != null)
        {
            new GetHtmlDocument("someUrlString").cancel(true);
        }

        while (this.htmlPage.getHtmlDocument() == null)
        {
            if (this.htmlPage.getHtmlDocument() != null)
            {
                new GetHtmlDocument("someUrlString").cancel(true);
            }
            else
            {
                new GetHtmlDocument("someUrlString").execute();
            }
        }
    }
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");

            // Get the HTML http://www.lyricsplanet.com/ document
            HtmlPage htmlPage = new HtmlPage(getParsedDocument(this.url));

            return 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");
        }
    }
public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }
public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}
   public Document getParsedDocument(String url)
    {
        try
        {
            return Jsoup.connect(url).get();
        }
        catch (IOException e) // On error
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return null; // Failed to connect to the url
    }

我忘记了
W/art:Suspending-all-threads-take:1.1ms
警告。我在运行应用程序时得到了这一点。但是当我调试应用程序时,我没有得到这个结果,我清楚地看到在
doInBackground()
方法中生成的
HtmlPage
对象得到了我想要的值。

这是因为你的
onCreate()
启动了
AsyncTask
然后通过while循环轮询,等待完成的数据。其他的线都快饿死了。您需要异步处理结果。尝试使用
处理程序
并让
onPostExecute()
在完成后发送消息。

只需调用
新的GetHtmlDocument(“someUrlString”).execute()并等待onPostExecute()中的结果。不需要使用while循环(这会阻塞UI线程)或调用cancel()(实际上,默认情况下它不做任何事情,请检查底部的链接)

要知道,

AsyncTask应仅用于耗时数秒的任务/操作

异步任务在单个后台线程上串行执行(来自API 11)。因此,长时间运行的工人可以阻止其他人


其他一些。

不完全清楚为什么在onCreate()中启动任务后立即取消该任务,这可能是问题所在。@Egor如果我从
AsyncTask
对象(非空
HtmlPage
对象)中得到我想要的,我就取消
AsyncTask
执行。顺便说一句,即使我删除了该行,它也会保持完全相同。AsyncTask只是-async,执行在不同的线程上运行,因此您不能期望调用execute()并在下一行代码中显示结果。@Egor我知道,但不幸的是,删除cancel语句不是问题所在。@Egor关于
挂起所有线程
的警告呢?
处理程序
您指的是类似的东西------或者在主
线程
上初始化的接口,这是
AsyncTask
类属性?谢谢你的帮助,伙计。你能看看这个吗?您可以使用在
onCreate
中创建的
处理程序。或者,如果操作正确,则直接在
onPostExecute
中执行操作。您需要小心使用
AsyncTask
,因为它不了解生命周期,如果允许它直接操作UI组件,可能会导致问题。本文将帮助解释:谢谢。我会检查一下。