AndroidにおけるHandlerメッセージングメカニズム

4433 ワード

Handlerは何に使いますか?
1)計画タスクを実行し、所定の時間に特定のタスクを実行し、タイマーをシミュレートすることができる
2)スレッド間通信.Androidのアプリケーションが起動すると、メインスレッドが作成され、メインスレッドはメッセージキューを作成して様々なメッセージを処理します.サブスレッドを作成すると、親スレッドで作成したHandlerオブジェクトをサブスレッドから取得でき、親スレッドのメッセージキューにメッセージを送信できます.AndroidはUIスレッドでインタフェースを更新する必要があるため、この方法で他のスレッドでインタフェースを更新することができる.
パフォーマンスの最適化を考慮すると、AndroidのUI操作はスレッドセキュリティではありません.これは、複数のスレッドがUIコンポーネントを同時に操作している場合、スレッドセキュリティの問題を引き起こす可能性があることを意味します.この問題を解決するために、AndroidはUIスレッドのみがActivityのUIコンポーネントを変更できるという簡単なルールを制定しました.
1つのプログラムが最初に起動されると、Androidは同時にメインスレッド(Main Thread)を起動し、メインスレッドは主にUIに関連するイベント、例えばユーザーのボタンイベント、ユーザーがスクリーンに接触するイベント、スクリーン描画イベントを処理し、関連するイベントを対応するコンポーネントに配布して処理する.したがって、プライマリスレッドはUIスレッドとも呼ばれることが多い.
Androidのメッセージングメカニズムは別の形式の「イベント処理」であり、このメカニズムは主にAndroidアプリケーションのマルチスレッド問題を解決するためである.AndroidプラットフォームはUIスレッドがActivityのUIコンポーネントを修正することを許可するだけで、新たに起動したスレッドがインタフェースコンポーネントの属性値を動的に変更できない.しかし,実際のAndroidアプリケーション開発では,特にアニメーションに関するゲーム開発では,新たに起動したスレッドにインタフェースコンポーネントの属性値を周期的に変更させる必要があり,Handlerのメッセージングメカニズムによって実現する必要がある.
Handlerクラスの概要
Handlerクラスの主な役割は2つあります.
1.新しく起動したスレッドでメッセージを送信します.
2、メインスレッドでメッセージを取得、処理する.
新規に起動したスレッドから送信されたメッセージを「適時」に処理できるようにするには、開発者がHandlerクラスでメッセージを処理する方法を書き換えるだけで、新規に起動したスレッドがメッセージを送信すると、それに関連付けられたMessageQueueにメッセージが送信され、一方、HandlerはMessageQueueからメッセージを取得して処理し続けます.これにより、Handlerクラスでメッセージを処理する方法がコールバックされます.
Handlerクラスは、メッセージを送信、処理するための方法を含む.
1、void handleMessage(Message msg):メッセージを処理する方法.この方法は通常書き換えに用いられる.
2、final boolean hasMessages(int what):メッセージキューにwhat属性が指定された値のメッセージに含まれているかどうかを確認します.
3、final boolean hsaMessages(int what,Object object):メッセージキューにwhat属性が指定された値であり、object属性が指定されたオブジェクトであるメッセージが含まれているかどうかを確認します.
4、複数のリロードされたMessage obtainMessage():メッセージを取得します.
5、sendEmptyMessage(int what):空のメッセージを送信します.
6、final boolean sendEmptyMessageDelayMills(int what,long delayMills):数ミリ秒後に空のメッセージを送信することを指定します.
7、final boolean sendMessage(Message msg):直ちにメッセージを送信する.
8、final boolean sendMessageDelayed(Message msg,long delayMillis):メッセージを送信する時間を指定します.
これらの方法により,プログラムはHandlerクラスを用いて容易にメッセージングを行うことができる.
Handler、Loop、MessageQueueの動作原理
Handlerの動作原理をよりよく理解するために、まずHandlerと一緒に動作するいくつかのコンポーネントを紹介します.
1.Message:Handlerが受け入れて処理するメッセージオブジェクト
2、Looper:スレッドごとに1つのLooperしか持てません.そのloopメソッドはMessageQueueのメッセージを読み取り,メッセージを読んだ後にメッセージを送信するHandlerに渡して処理する.
3、MessageQueue:Messageを管理するために先進的な方法を採用したメッセージキュー.プログラムがLooperオブジェクトを作成すると、そのコンストラクタにLooperオブジェクトが作成されます.Looperが提供するコンストラクタのソースコードは次のとおりです.

private Looper()
{
mQueue=new MessageQueue();
mRun=true;
mThread=Thread.currentThread();
}

このコンストラクタはprivate修飾を使用し、プログラマがコンストラクタからLooperオブジェクトを作成できないことを示します.上記のコードから明らかなように、プログラムはLooperを初期化する際に、メッセージの管理を担当するMessageQueueを作成します.
1、Handler:その役割は2つあります.メッセージの送信とメッセージの処理です.プログラムはHandlerを使用してメッセージを送信します.Handlerによって送信されたメッセージは指定されたMessageQueueに送らなければなりません.つまり、Handlerが正常に動作するようにするには、現在のスレッドにMessageQueueがある必要があります.そうしないと、メッセージはMessageQueueに保存されません.ただし、MessageQueueはLooperが管理しています.つまり、Handlerを正常に動作させるには、現在のスレッドにLooperオブジェクトが1つ必要です.現在のスレッドにLooperオブジェクトがあることを保証するために、次の2つのケースに分けられます.
1.メインUIスレッドでは、システムがLooperオブジェクトを初期化しているので、プログラムは直接Handlerを作成し、Handlerを通じてメッセージを送信し、処理することができる.
2、プログラマが自分で起動したサブスレッド.プログラマは自分でLooperオブジェクトを作成し、起動しなければならない.Looperオブジェクト呼び出しのprepare()メソッドを作成すればよい.
prepare()メソッドは、各スレッドに最大1つのLooperオブジェクトしかないことを保証します.prepare()メソッドのソースコードは次のとおりです.

public static final void prepare()
{
if(sThreadLocal.get()!=null)
{
throw new RuntimeException("Only one Looper may be createed per thread");
}
sThreadLocal.set(new Looper());
}

次に、Looperの静的loop()メソッドを呼び出して起動します.loop()メソッドは,デッドサイクルを用いてMessageQueue中のメッセージを絶えず取り出し,取り出したメッセージを対応するHandlerに分けて処理する.
まとめると、Looper、MessageQueue、Handlerのそれぞれの役割は以下の通りである.
1、Looper:各スレッドには1つのLooperしかありません.MessageQueueを管理し、MessageQueueからメッセージを絶えず取り出します.メッセージを対応するHandler処理に分割する.
2、MessageQueue:Looperが管理する.Messageを管理するために先進的な方法を採用しています.
3、Handler:Looperが管理するMessageQueueにメッセージを送信し、Looperが割り当てたメッセージの処理を担当します.
スレッドでHandlerを使用するには、次の手順に従います.
1、Looperを呼び出すprepare()メソッド現在のスレッドに対してLooperオブジェクトを作成し、Looperオブジェクトを作成すると、そのコンストラクタはそれに付属するMessageQueueを作成します.
2.Looperができたら、Handlerサブクラスのインスタンスを作成し、handlerMessage()メソッドを書き換えます.このメソッドは、他のスレッドからのメッセージの処理を担当します.
3、Looperを呼び出すloop()メソッドLooperを起動します.
以上、筆者がご紹介したAndroidでのHandlerメッセージングメカニズムをご紹介しますので、ご協力をお願いします!