Thread.AsyncTaskでのjoin()の使い勝手


に質問
Android Emailでは、受信サーバと送信サーバを設定するときに「次へ」をクリックすると、進捗ボックスがポップアップされ、サーバ設定チェックが実行されます.ユーザ設定情報が正しくない場合、検証を実行すると、約1分かけて検証され、最後に設定情報が正しくないことが示されます.ユーザーが待機中に「キャンセル」をクリックし、次のステップをクリックすると、表示され、待機プロンプトボックスがポップアップされず、検証も実行されません.
ぶんせき
ソースコードを分析すると、「次へ」をクリックしてチェックを実行すると、AsyncTaskが実行され、doIngBackground()でsocket接続を開き、対応するチェックを完了します.同時に待機プロンプトボックスがポップアップされます.ユーザーが「キャンセル」をクリックすると、このAsyncTaskが終了し、AsyncTaskが再生成されて実行されます.
しかし、debugにより、後のAsyncTaskは実際に実行されていないことが分かった.なぜなら、前のTaskがネットワークチェックにブロックされているからです.Androidドキュメントを調べると、AsyncTaskは、非同期処理クラスであることがわかります.doInBackgroundを実行するスレッドが新しく生成されます.対外的には,開発者はこのスレッドの参照を取得することができず,取得してもsocket接続やIO操作のようにブロックを招くジョブに対しては,強制interruptスレッドはブロックを終了することができない.
結論
その後、怒ったAsyncTaskが正常に実行されないように、次のことを覚えておいてください.
doInBackground()をブロックしないで、ブロックを引き起こす可能性のある操作を完了するためにスレッドを新規に作成する必要があります.
 
解決策
Thread.join()
        @Override
        protected Object doInBackground(Void... params) {
            Thread thread = new Thread(){
                   public void run(){
                          mResult = getFromServer();//         
                   }
            };
            thread.start();
            try{
                thread.join(); //       ,  thread    ,     ,        
            } catch (InterruptedException e) {
                // Thread.join()   interrupt,  AsyncTask.cancel(true);      
                return null;
            }