AsyncTask onPostExecute()永远不会被调用+ W / art:挂起所有线程:1.1ms

时间:2016-04-09 18:10:08

标签: android multithreading asynchronous android-asynctask jsoup

我知道有很多关于此事的AsyncTask个问题,但没有一个能帮助我。

我有AsyncTask使用HTML处理一些Jsoup解析。

我无数次(实际上)调试了应用程序,并且在调用i 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();
            }
        }
    }

AsyncTask内部类:

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");
        }
    }

onPostExecute()中使用的方法:

public void setHtmlPage(HtmlPage htmlPage)
    {
        this.htmlPage = htmlPage;
    }

HtmlPage.java:

public class HtmlPage
{
    private Document htmlDocument;

    public HtmlPage(Document htmlDocument)
    {
        this.htmlDocument = htmlDocument;
    }
}

在doInBackground()中使用的方法:

   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
    }

我想问题是主Thread永远不会有机会使用我的onPostExecute()的{​​{1}}参数调用Generic方法或其他内容我的AsyncTask课程的实施。

任何建议都将非常感谢。

修改

我忘记了AsyncTask警告。我得到了运行应用程序。但是当我调试应用程序时,我没有得到它,我清楚地看到W/art: Suspending all threads took: 1.1ms方法中生成的HtmlPage对象获得了我想要的值。

2 个答案:

答案 0 :(得分:1)

这是因为您的onCreate()启动AsyncTask,然后通过while循环进行轮询,等待已完成的数据。它挨了任何其他线程。您需要异步处理结果。尝试使用Handler并让onPostExecute()在完成后发送消息。

答案 1 :(得分:1)

只需调用new GetHtmlDocument("someUrlString").execute();并在onPostExecute()中等待结果。不需要使用while循环(阻止你的UI线程)或调用cancel()(实际上它默认不做任何事情,检查底部的链接)。

请注意,

AsyncTask只应用于需要几秒钟的任务/操作;

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

其他一些gotchas