Android AsyncTask基礎知識整理

5032 ワード

一、AsyncTaskの紹介
AsyncTaskは、Androidによってカプセル化された軽量レベルの非同期クラス(使い勝手、コードの概要)である抽象的な汎用クラスであり、スレッド内でバックグラウンドタスクを実行し、実行結果と進捗状況をプライマリスレッドに渡し、プライマリスレッドでUIを更新することができます.
AsyncTask内部には2つのスレッドプール(SerialExecutorとTHREAD_POOL_EXECUTOR)と1つのHandler(InternalHandler)がカプセル化されている.
  • SerialExecutorスレッドプールは、タスクのキューに使用され、実行する必要がある複数の時間のかかるタスクを順番に並べます.
  • THREAD_POOL_EXECUTORスレッドプールは、実際にタスクを実行するスレッドプールです.
  • InternalHandlerはスレッドの切り替えに使用され、ワークスレッドからプライマリスレッドに切り替えられます.

  • 二、AsyncTaskの汎用パラメータ
    public abstract class AsyncTask 
    
  • Params:非同期タスクを開始するときに入力されるパラメータタイプ.execute()で入力され、doInBackground(Void...params)のparamsタイプと同じです.
  • Progress:実行の進捗状況は、onProgressUpdate(Integer...values)のvaluesタイプと一致し、一般的にはIntegerです.
  • Result:doInBackgroundが返すパラメータタイプと一致し、onPostExecuteのパラメータと一致する終了した戻り値を実行します.

  • AsyncTaskが特定のパラメータを伝達する必要がないと判断した場合、この3つの汎用パラメータはVoidで置き換えることができる.
    三、AsyncTaskの核心方法
    onPreExecute()
  • バックグラウンドタスクの実行が開始される前に呼び出され、メインスレッド呼び出しでは、進捗バーダイアログボックスなどのインタフェースの初期化操作を行うために使用されます.

  • doInBackground(Params...)
  • この方法のすべてのコードはサブスレッドで実行され、ここではすべての時間のかかる操作を処理する必要があります.
  • この方法はUI操作を行うことができず、フィードバックの進捗などのUIを更新する必要がある場合はpublishProgress(Progress...)を呼び出すことができる.方法で完成します.

  • onProgressUpdate(Progress...)
  • バックグラウンドタスクがpublishProgress(Progress...)を呼び出すとメソッドの後、このメソッドが呼び出され、メソッドに含まれるパラメータはバックグラウンドタスクから渡されます.
  • この方法はUIを操作することができ、メインスレッドで行い、パラメータの値を利用してインタフェース要素を対応する更新することができる.

  • onPostExecute(Result)
  • doInBackground(Params...)実行が完了しreturn文で戻ると、このメソッドが呼び出されます.
  • から返されたデータはパラメータとしてこのメソッドに渡され、書き込みUI操作を行い、進捗ボックスを注意したり閉じたりすることができます.

  • 上記の方法の実行順序:onPreExecute()-->doInBackground()-->publishProgress()-->onProgressUpdate()-->onPostExecute()
    更新の進行状況を実行する必要がない場合:onPreExecute()-->doInBackground()-->onPostExecute()
    AsyncTaskはまた、非同期タスクをキャンセルし、メインスレッドで呼び出すcancel(boolean)メソッドも提供しています.cancel(boolean)が呼び出されると、onPostExecute()は呼び出されず、onCancelled()メソッドが呼び出されます.しかし、本当にタスクをキャンセルするわけではありません.このタスクをキャンセル状態に設定しただけで、doInBackground()でタスクを終了すると判断する必要があります.
    四、AsyncTaskの簡単な使用
    class DownloadTask extends AsyncTask {  
      
        @Override  
        protected void onPreExecute() {  
            progressDialog.show();  
        }  
      
        @Override  
        protected Boolean doInBackground(Void... params) {  
            try {  
                while (true) {  
                    int downloadPercent = doDownload();  
                    publishProgress(downloadPercent);  
                    if (downloadPercent >= 100) {  
                        break;  
                    }  
                }  
            } catch (Exception e) {  
                return false;  
            }  
            return true;  
        }  
      
        @Override  
        protected void onProgressUpdate(Integer... values) {  
            progressDialog.setMessage("      :" + values[0] + "%");  
        }  
      
        @Override  
        protected void onPostExecute(Boolean result) {  
            progressDialog.dismiss();  
            if (result) {  
                Toast.makeText(context, "    ", Toast.LENGTH_SHORT).show();  
            } else {  
                Toast.makeText(context, "    ", Toast.LENGTH_SHORT).show();  
            }  
        }  
    }
    

    ここではダウンロードタスクを模倣し、doInBackground()はダウンロードロジックを実行し、onProgressUpdate()は現在のダウンロード進捗状況を表示し、onPostExecute()はタスク実行結果を提示する.タスクを開始する場合は、次のコードを呼び出すだけです.
    new DownloadTask().execute();  
    

    五、AsyncTaskの使用上の注意事項
  • 非同期タスクのインスタンスはUIスレッドで作成する必要があります.すなわち、AsyncTaskオブジェクトはUIスレッドで作成する必要があります.
  • execute()メソッド、cancelled()メソッドは、UIスレッドで呼び出さなければなりません.
  • はdoInBackground()メソッドでUIを更新できません.
  • タスクインスタンスは1回しか実行できません.2回目の実行では例外が放出されます.

  • 六、AsyncTaskの欠陥
    ライフサイクル:
  • AsyncTaskはどのコンポーネントにもライフサイクルをバインドしないので、ActivityまたはFragmentでAsyncTaskを作成する場合はonDestory()でcancel(boolean)メソッドを呼び出すことが望ましい.とにかくAsyncTaskを正しくキャンセルすることを確保しなければなりません.

  • メモリの漏洩:
  • AsyncTaskがActivityの非静的内部クラスとして宣言された場合、AsyncTaskはActivityの作成に対する参照を保持します.Activityが破棄された場合、AsyncTaskはバックグラウンドで実行されます.この参照はメモリに保持され続け、Activityが回収されず、メモリが漏洩します.

  • cancel(boolean)は必ずしも使いやすいとは限らない.
  • AsyncTaskが完了した場合、または他の理由でキャンセルできない場合、cancel(boolean)を呼び出すのは実際の効果はありません.doInBackground()メソッドは引き続き実行されますが、onPostExecute()は実行されません.booleanパラメータmayInterruptIfRunningは、Task
  • を直ちにstopするかどうかを決定する
    結果が失われました:
  • 画面が回転したり、Activityがバックグラウンドでシステムによって殺されたりすると、Activityの再作成が起こり、以前に実行されていたAsyncTask(非静的内部クラス)は以前のActivityの参照を持っていたが、この参照は無効になり、onPostExecute()を呼び出してUIを更新しても有効ではない.

  • シリアルまたはパラレル:
  • AsyncTaskはデフォルトでシリアルで実行されますが、executeOnExecutor(Executor)を設定することで複数のAsyncTask並列を実現することもできます.

  • 七、AsyncTaskとHandlerの関係
  • それらの関係は大きくなく、AsyncTaskは本質的にHandlerのパッケージであり、内部には独自に維持されたスレッドプールがあるため、レベルのものではないと言える.
  • は、UIスレッドのブロックを回避するために、いくつかのコードを非同期で実行することができるいくつかの同じ目的を有する.

  • AsyncTaskのソースコードの理解については、後で理解してから、また補充して、再び技術のない涙を残しました~最後に参考博文を奉納して、結局東拼西凑(顔を覆う):Androidの中のスレッド状態のAsyncTaskはAsyncTaskの使用と欠陥を詳しく理解します