3

これについて多くの質問がありますが、何も私を助けてくれませんでした。AsyncTask onPostExecute()は決して呼び出されません+ W:art:すべてのスレッドを中断しました:1.1ms

Jsoupを使用して、一部のHTMLの解析を処理するAsyncTaskを取得しました。

は、私が(本当に)アプリ数え切れないほどの時間をデバッグし、 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内部クラス:onPostExecuteに使用

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

HtmlPage.java:d​​oInBackground()で使用

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()メソッドを呼び出すための機会を得ることはありませんメインThreadですか、 GenericのパラメータがAsyncTaskであるか、またはAsyncTaskというクラスを実装したものです。

ご意見はお寄せください。

EDIT:

私はW/art: Suspending all threads took: 1.1ms警告を忘れてしまいました。私はアプリを実行するためにそれを取得します。しかし、私はアプリをデバッグするとき私はそれを取得しないと私は明らかにdoInBackground()メソッドで生成されているHtmlPageオブジェクトが私が欲しい値を取得することがわかります。

+0

onCreate()でタスクを開始した直後にタスクをキャンセルする理由は完全にはわかりませんが、これが問題になる可能性があります。 – Egor

+0

@Egorもし私が 'AsyncTask'でないものが' HtmlPage'オブジェクトではない場合、私は 'AsyncTask'の実行をキャンセルします。そして、私はその行を削除しても、それはまったく同じままです。 – God

+0

AsyncTaskは単なるasyncです。実行は別のスレッドで実行されるため、execute()を呼び出して次のコード行に結果を返すことはできません。 – Egor

答えて

1

new GetHtmlDocument("someUrlString").execute();を呼び出して、結果を待つのはonPostExecute()です。 whileループ(UIスレッドをブロック)やcancel()を呼び出す必要はありません(実際にはデフォルトでは何もしません)。

はAsyncTaskのみかなりの数秒かかるタスク/操作のために使用すべきである

、注意してください。

AsyncTasksは、1つのバックグラウンドスレッド(API 11から)でシリアルに実行されます。だから、長く走っている労働者は他人を塞ぐことができる

その他gotchas

+0

ありがとうございました。私はそれを越えます。 – God

1

あなたのonCreate()AsyncTaskをキックオフしてから、whileループ経由でポーリングして、完了したデータを待っているからです。それは他のスレッドから飢えている。結果を非同期に処理する必要があります。 Handlerを使用して、完了したらonPostExecute()にメッセージを送信してください。

+0

'Handler'では、そのようなものを参照しています。http://stackoverflow.com/questions/11713625/android-handler-for-asynctask -----またはメインの' Thread'で初期化されるインターフェースです。 AsyncTaskクラスのプロパティの一部?助けてくれてありがとう。 – God

+0

これを参照できますか? http://stackoverflow.com/questions/36528668/asynctask-oncancelledobject-never-invoked-after-asynctask-canceltrue – God

+0

あなたの 'onCreate'で作成された' Handler'を使うことができます。または、正しく実行された場合は、 'onPostExecute'で直接アクションを実行してください。ライフサイクルに対応していないため、AsyncTaskを注意する必要があります。また、UIコンポーネントを直接操作することができれば、問題を引き起こす可能性があります。この記事は説明に役立ちます:http://po.st/Cei3m2 –

関連する問題