3

Ich weiß, es gibt eine Menge von AsyncTask Fragen dazu, aber keine geschah mir zu helfen.AsyncTask onPostExecute() wird nie aufgerufen + W/art: Suspending alle Threads nahm: 1.1ms

Ich habe eine AsyncTask, die einige HTML Parsing mit Jsoup behandelt.

ich gedebuggt die App unzählige Male (wirklich) und nach doInBackground() Methode i die Werte i bis onPostExecute() Methode senden möchten bekommen genannt, aber das Problem der onPostExecute() Methode nie aufgerufen.

Ich denke, es ist etwas einfaches, das durch mich gleiten.

Nur relevanten 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 innere Klasse:

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

Methode verwendet, 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; 
    } 
} 

Methode, die in doInBackground verwendet():

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 
    } 

Ich denke, das Problem ist, mit dem Haupt Thread, die nie eine Chance onPostExecute() Methode aufrufe werden oder etwas mit den Generic Parametern meiner AsyncTask oder etwas mit meiner Implementierung meiner AsyncTask Klasse.

Alle Vorschläge werden sehr geschätzt.

EDIT:

ich vergaß die W/art: Suspending all threads took: 1.1ms Warnung. Ich bekomme das zum Ausführen der App. Aber wenn ich die App debuggen bekomme ich das nicht und ich sehe deutlich, dass das HtmlPage Objekt, das in der doInBackground() Methode generiert wurde, den Wert bekomme, den ich will.

+0

Es ist nicht ganz klar, warum Sie die Aufgabe gleich nach dem Start in onCreate() abbrechen, dies könnte das Problem sein. – Egor

+0

@Egor Wenn ich bekomme, was ich wollte von der 'AsyncTask', die ein nicht null' HtmlPage' Objekt ist, lehne ich einfach die 'AsyncTask' Ausführung ab. Und BTW, auch wenn ich diese Zeile entferne, bleibt es genau gleich. – God

+0

AsyncTask ist nur das - async, die Ausführung läuft auf einem anderen Thread, so dass Sie nicht erwarten können, execute() aufzurufen und das Ergebnis in der nächsten Codezeile zu haben. – Egor

Antwort

1

Rufen Sie einfach new GetHtmlDocument("someUrlString").execute(); und warten Ergebnis in der onPostExecute(). Es ist nicht notwendig, die while-Schleife zu verwenden (die den UI-Thread blockiert) oder cancel() aufzurufen (tatsächlich wird standardmäßig nichts unternommen, siehe Link unten).

bewusst sein,

AsyncTask sollte nur für Aufgaben/Operationen verwendet werden, die nicht wenige Sekunden in Anspruch nehmen;

AsyncTasks werden seriell auf einem einzelnen Hintergrundthread ausgeführt (aus API 11). So lange laufende Arbeiter können andere blockieren;

Einige andere gotchas.

+0

Vielen Dank. Ich werde darüber gehen. – God

1

Es ist, weil Ihre onCreate() startet die AsyncTask dann Umfragen über die While-Schleife, warten auf abgeschlossene Daten. Es verhungert jeden anderen Thread. Sie müssen das Ergebnis asynchron verarbeiten. Versuchen Sie es mit einem Handler und onPostExecute() senden Sie eine Nachricht, wenn es fertig ist.

+0

Von 'Handler' beziehen Sie sich auf so etwas http://stackoverflow.com/questions/11713625/android-handler-for-asynctask---- oder eine Schnittstelle, die auf dem Haupt' Thread' initialisiert und das ist a Teil der 'AsyncTask'-Klasseneigenschaften? Danke für deine Hilfe. – God

+0

Können Sie sich darauf beziehen? http://stackoverflow.com/questions/36528668/asynctask-oncancelledobject-never-invoked-after-asynctask-canceltrue – God

+0

Sie könnten einen 'Handler' verwenden, der in Ihrem' onCreate' erstellt wurde. Oder, wenn Sie es richtig gemacht haben, führen Sie die Aktion direkt im 'onPostExecute' aus. Sie müssen mit 'AsyncTask' vorsichtig sein, da es nicht lebenszyklusabhängig ist und wenn es erlaubt wird, UI-Komponenten direkt zu manipulieren, kann dies zu Problemen führen. Dieser Artikel wird helfen, zu erklären: http://po.st/Cei3m2 –

Verwandte Themen