ソースは、AsyncTaskを理解します

見直し後のように、次の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 - 14。 )); コアCPUのプール2の数倍のスレッドの最大数// 1 +。プライベート静的最終INT MAXIMUM_POOL_SIZE CPU_COUNT * = 2 + 1 ; //スレッドの生存期間の非コア数は30秒だったプライベート静的最終INT = KEEP_ALIVE_SECONDS 30




1 
2
3
ブロッキングキュー長が128 
プライベート 静的 最終 BlockingQueueの<Runnableを> = sPoolWorkQueue 新しい新しい LinkedBlockingQueue <Runnableを>(128)。

重要な方法で使用します。
1 
2
3
4
5
6
7
8
//タスクの必要性を開始する前に、操作:メインスレッド
保護 のボイド {}
//抽象クラスが実装しなければなりません。:消費操作子スレッドは、
保護された 抽象結果doInBackgroundPARAMS ... の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はじめに

  1. RunnableをArrayDequeキュー管理によってSerialExecutor我々はタスクの多くを開始し、最初のexecute()メソッドの最初の実行待ち行列の最後尾に入ってくるRunnableオブジェクトを追加する提案ArrayDequeの()メソッドを呼び出し決定mActiveオブジェクトがヌルに等しくない場合、その後、nullが確かに最初に実行されるので、scheduleNext()メソッドを呼び出します。キューは、ヘッドからの値、及びmActiveオブジェクトに割り当てられ、次に検索されたRunnableオブジェクトを実行するために、THREAD_POOL_EXECUTOR.execute(mActive)メソッドを呼び出します。
  2. 実行しscheduleNext修飾同期化され、これら2つの方法が同じオブジェクトのロックを持って、実行する方法、r.run()メソッドでは、同時に実行できない実行が完了すると、最終的な時間のかかるタスクのサブスレッドであります最終的にはトップのタスクを削除するにはscheduleNextを呼び出すに入ります。
  3. ビッグボックス  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:
// There is only one 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を使用するだけでなく、呼び出す方法を知っているが、それがどのように動作するかを知りませんでしたされています(アプリケーション内のスレッドの乱用、それはあまりにも多くのスレッドが発生します)深刻な問題を引き起こし、それが実行前、実行プログレスバーの更新を提供し、コールバック操作を実行した後、私たちの利用が促進されました。

おすすめ

転載: www.cnblogs.com/sanxiandoupi/p/11711195.html