見直し後のように、次のAsyncTaskのソースを理解するのは簡単。
パッケージ:android.os。
機能:非同期要求の際には、その上の子スレッドとメインスレッドとの間の通信を解決します。
以下のような:抽象クラスので、インスタンス化することはできません、私たちはそれと再利用を継承する必要があります。
ソース決意
AsyncTaskクラスが含まれています:
静的内部クラス3 [AsyncTaskResult、InternalHandler、SerialExector]
静的内部抽象クラス[WorkerRunnable]
列挙クラス[状態]
スレッドプールのセクション:
1 2 3 4 5 6 7 8 9 10 11 12
/ ** *ために使用することができる{@linkキュータ} 実行 並列にタスクを。 * / パブリック 静的 最終 キュータTHREAD_POO L_EXECUTOR。 静的 { ThreadPoolExecutor threadPoolExecutor = 新しい ThreadPoolExecutor( CORE_POOL_SIZE、MAXIMUM_POOL_SIZE、KEEP_ALIVE_SECONDS、TimeUnit.SECONDS、 sPoolWorkQueue、sThreadFactory)。 threadPoolExecutor.allowCoreThreadTimeOut(真の); THREAD_POO L_EXECUTOR = threadPoolExecutor。 }
これらのパラメータは:
1 2 3 4 5 6 7
プライベート 静的 最終 int型 CPU_COUNT = Runtime.getRuntime()availableProcessors(); プライベート 静的 最終 INT CORE_POOL_SIZE Math.max =( 2 、Math.min(CPU_COUNT - 1 、 4。 )); プライベート 静的 最終 INT MAXIMUM_POOL_SIZE CPU_COUNT * = 2 + 1 ; プライベート 静的 最終 INT = KEEP_ALIVE_SECONDS 30 。
1 2 3
ブロッキングキュー長が 128 プライベート 静的 最終 BlockingQueueの<Runnableを> = sPoolWorkQueue 新しい新しい LinkedBlockingQueue <Runnableを>( 128 )。
重要な方法で使用します。
1 2 3 4 5 6 7 8
保護 のボイド ( ) {} 保護された 抽象 結果 doInBackground ( PARAMS ... のparams ) ; 保護された 無効 onProgressUpdate ( 進捗...値 ) {} 保護された 無効 onPostExecute ( 結果の検索結果を ) {}
実行方法を実行します。
1 2 3 4 5 6 7 8
最初:私たちは、パラメータスケジューラと渡す必要が 公共の 最終 AsyncTask < paramsは 、進捗状況、 結果 (執行Execの、> executeOnExecutor のparamsを ... のparams ) 第二:デフォルトのスケジューラを使用して、内部コール最初の方法、渡されたパラメータ 公共 決勝 AsyncTask < paramsは 、進捗状況、 結果は >(実行 のparams ... のparamsを ) 第三:実行可能なデフォルトのスケジューラの方法を実行し 、パブリック 静的 ボイド(Runnableを実行可能)を実行します
デフォルトのスケジューラ:sDefaultExecutor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
プライベート 静的 揮発性 キュータsDefaultExecutor = SERIAL_EXECUTOR。 公共の 静的な 最終 キュータSERIAL_EXECUTOR = 新しい SerialExecutor(); プライベート 静的 クラス SerialExecutorは 実装 キュータ { 最終 ArrayDeque <Runnableを> mTasks = 新しい ArrayDequeを<Runnableを>(); RunnableをmActive; 公共 同期 ボイドが 実行 ( 最終 のRunnable r)を { mTasks.offer( 新しい Runnableを(){ 公共 ボイド ラン () { 試みる { r.run(); } 最後に { scheduleNextを(); } } })。 もし (mActive == NULL ){ scheduleNext()。 } } 保護された 同期 のボイド scheduleNext () { 場合 ((mActive = mTasks.poll())!= nullの ){ THREAD_POOL_EXECUTOR.execute(mActive)。 } } }
SerialExecutorはじめに
RunnableをArrayDequeキュー管理によってSerialExecutor我々はタスクの多くを開始し、最初のexecute()メソッドの最初の実行待ち行列の最後尾に入ってくるRunnableオブジェクトを追加する提案ArrayDequeの()メソッドを呼び出し決定mActiveオブジェクトがヌルに等しくない場合、その後、nullが確かに最初に実行されるので、scheduleNext()メソッドを呼び出します。 キューは、ヘッドからの値、及びmActiveオブジェクトに割り当てられ、次に検索されたRunnableオブジェクトを実行するために、THREAD_POOL_EXECUTOR.execute(mActive)メソッドを呼び出します。
実行しscheduleNext修飾同期化され、これら2つの方法が同じオブジェクトのロックを持って、実行する方法、r.run()メソッドでは、同時に実行できない実行が完了すると、最終的な時間のかかるタスクのサブスレッドであります最終的にはトップのタスクを削除するにはscheduleNextを呼び出すに入ります。
ビッグボックス AsyncTaskソースを理解 タスクに毎回mTasks.offerを、それが実行される最初、先着順を確保ArrayDeque尾に配置されています。
executeOnExecutor()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
public final AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params ) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running." ); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)" ); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params ; exec.execute(mFuture); return this ; }
executeOnExecutor方法中执行了onPreExecute(),然后执行了exec.execute(mFuture);
其中Future为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mFuture = new FutureTask<Result>(mWorker) { protected void done () { try { postResultIfNotInvoked(get()); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occurred while executing doInBackground()" , e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null ); } } };
从executeOnExecutor方法执行中可以看出,AsyncTask内,在主线程中先执行了onPreExecute()方法,然后在线程中调用了doInBackground()方法,任务执行完成后,通过postResult 或者 postResultIfNotInvoked 方法发送消息到主线程
postResult方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
private void postResultIfNotInvoked (Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } } private Result postResult (Result result) { @SuppressWarnings ("unchecked" ) Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this , result)); message.sendToTarget(); return result; }
postResult方法的作用即为任务结束后,发送message给主线程,反馈Result结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
private static class InternalHandler extends Handler { public InternalHandler (Looper looper) { super (looper); } @SuppressWarnings ({"unchecked" , "RawUseOfParameterizedType" }) public void handleMessage(Message msg) { AsyncTaskResult <?> result = (AsyncTaskResult <?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT : result.mTask.finish(result.mData[0 ]); break ; case MESSAGE_POST_PROGRESS : result.mTask.onProgressUpdate(result.mData); break ; } } }
接收结果的为InternalHandler类,接收到结果并调用mTask的finish方法并把结果返回过去。
finish方法
1 2 3 4 5 6 7 8
private void finish (Result result ) { if (isCancelled ()) { onCancelled (result ); } else { onPostExecute (result ); } mStatus = Status .FINISHED; }
当Task结束后,会调用finish方法,如AsyncTask已经被取消,则会返回onCancelled回调,当未被取消则会调用onPostExecute回调。因此,onPostExecute回调也是主线程。
总结:
過去には、我々はソースコードを見ることができる分析した後、私たちは良いスレッド管理を行うためにためAsyncTask、AsyncTaskを使用するだけでなく、呼び出す方法を知っているが、それがどのように動作するかを知りませんでしたされています(アプリケーション内のスレッドの乱用、それはあまりにも多くのスレッドが発生します)深刻な問題を引き起こし、それが実行前、実行プログレスバーの更新を提供し、コールバック操作を実行した後、私たちの利用が促進されました。