Androidソース分析-Handlerの同期バリアメカニズム
5491 ワード
は毎日Handler問答Handlerはみんながもっとよく知っているクラスであるべきで、その中に同期バリアのメカニズムがあって、あなたはどのくらい知っていますか? Handlerの同期バリア機構(sync barrier) 1.Handlerの非同期メッセージ
同期バリアを紹介するとき,まずHandlerの非同期メッセージを見てみよう.通常、Handlerを使用してタスクキューに追加した は、 一般的には、非同期メッセージと同期には差はありませんが、同期バリアがオンになると差があります.
2.同期バリア
一般に、
3.非同期メッセージの処理
同期バリアを開き、タスクキューに非同期メッセージをpostした後、Looperがポーリング中に同期バリアに遭遇すると、タスクキュー内で非同期メッセージが見つかります.具体的なコードを見てみましょう.
4.応用
同期バリアの原理を理解しましたが、何の役割がありますか?また、注意深い学生は、Api 28バージョンでは
Handler
のメカニズムに詳しいと思っていたが、最近、洋神のwanAndroidでHandler
に関する質問を見て、これは確かに知識の盲点であることを認めざるを得なかった.そこでちょうど暇な時間に簡単に研究してみましたが、その原理を簡単に分析します.本文の参考資料:同期バリアを紹介するとき,まずHandlerの非同期メッセージを見てみよう.通常、Handlerを使用してタスクキューに追加した
Message
は同期されています.非同期のMessage
を追加したい場合は、次の2つの方法で行います.Handler
の構造方法にはasync
のパラメータがあり、new Handlerのときにtrueと伝えればよいが、その後このHandler
を用いて追加されたMessage
は非同期である. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
Message
オブジェクトを作成するときに、Message
のsetAsynchronous
メソッドを直接呼び出す.2.同期バリア
一般に、
MessageQueue
は、一定の順序で厳格に実行される.しかし、この時、高優の任務が実行される必要がある場合は、どうすればいいのでしょうか.Messageの実行時間を直接現在時間に設定すればいいという人もいますが、キューに似たようなMessage
が複数ある場合、Message
が次回実行できる保証はありません(優れたタスクでも、実行中のタスクを中断することはできません.ジルコニアこの場合、同期バリアが必要です.優れたタスクを実行する必要がある場合は、キュー内の同期メッセージの実行を阻害するために、タスクキューに同期バリアを挿入できます.同期バリアの本質は、現在のLooper
がタスクキューから同期バリアを取り出した後、タスクキューから最初の非同期メッセージを取り出して実行することである.同期バリアと非同期メッセージの組み合わせにより、メッセージが直ちに実行される目的を達成することができる.どうやって同期バリアを開きますか?MessageQueue
のpostSyncBarrier
メソッドを呼び出して開くことができ、そのコードも非常に簡単です. private int postSyncBarrier(long when) {
// Enqueue a new sync barrier token.
// We don't need to wake the queue because the purpose of a barrier is to stall it.
synchronized (this) {
final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
msg.arg1 = token;
Message prev = null;
Message p = mMessages;
if (when != 0) {
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
}
if (prev != null) { // invariant: p == prev.next
msg.next = p;
prev.next = msg;
} else {
msg.next = p;
mMessages = msg;
}
return token;
}
}
postSyncBarrier
メソッドが呼び出されると、同期バリアであるMessageを表すtarget nullのMessageがタスクキューに挿入されます.3.非同期メッセージの処理
同期バリアを開き、タスクキューに非同期メッセージをpostした後、Looperがポーリング中に同期バリアに遭遇すると、タスクキュー内で非同期メッセージが見つかります.具体的なコードを見てみましょう.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
// Stalled by a barrier. Find the next asynchronous message in the queue.
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
上のコードから、MessageQueueがtargetがnullのMessageを取得すると、後で非同期メッセージが見つかり、実行されることを知っています.もちろん、非同期メッセージが取得されない場合、nextPollTimeoutMillis
は−1に設定され、非同期メッセージが1つあるまでキューがスリープされる.4.応用
同期バリアの原理を理解しましたが、何の役割がありますか?また、注意深い学生は、Api 28バージョンでは
postSyncBarrier
メソッドがhideと表記されていることを発見するはずです.つまり、グーグルのお父さんは私たちに使用することをお勧めしません.しかし、ViewRootImpl
のscheduleTraversals
メソッドでは、システムのソースコードから関連するアプリケーションを見つけることもできます. void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}
前にこの部分のコードを見たことがあるかもしれませんが、なぜこのようにPost Messageに来たのか分からないかもしれません.同期バリアを理解した後,3つのプロセスが直ちに実行できるようにしたことが分かった.これにより、すぐに実行するタスクがある場合や、Viewをクリックしてすぐに応答する必要がある場合は、同期バリアを通じて実行することができます.現在postSyncBarrier
メソッドはhideと表記されているが、オプションのメソッドも少なくない.