AsyncTask onPostExecute() is never called + W/art: Suspending all threads took: 1.1ms

匿名 (未验证) 提交于 2019-12-03 00:59:01

问题:

I know there a lot of AsyncTask questions about this but none happened to help me.

I got an AsyncTask that handles some HTML parsing using Jsoup.

I debugged the app countless times(really) and after doInBackground() method called i get the values i want to send to onPostExecute() method but the problem the onPostExecute() method is never called.

I guess it's something simple that slip through me.

Just relevant code.

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 inner class:

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

Method used in onPostExecute():

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

HtmlPage.java:

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

Method that used in 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     } 

I guess the problem is with the main Thread that never gets a chance to call onPostExecute() method or something with the Generic parameters of my AsyncTask or something with my implementation of my AsyncTask class.

Any suggestions will be very appreciated.

EDIT:

I forgot about the W/art: Suspending all threads took: 1.1ms warning. I get that for running the app. But when i debug the app i don't get that and i clearly see that the HtmlPage object that's been generated in the doInBackground() method get the value i want.

回答1:

Just call new GetHtmlDocument("someUrlString").execute(); and wait result in the onPostExecute(). There is no need to use while loop (that blocks your UI thread) or to call cancel() (actually it doesn't do anything by default, check link at the bottom).

Be aware,

AsyncTask should only be used for tasks/operations that take quite few seconds;

AsyncTasks are executed serially on a single background thread (from API 11). So long running worker can block others;

Some other gotchas.



回答2:

It's because your onCreate() kicks off the AsyncTask then polls via the while loop, waiting for completed data. It's starving off any other thread. You need to handle the result asynchronously. Try using a Handler and have onPostExecute() send a message when it is done.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!