Android:Handlerメッセージメカニズム(二)-Handlerメッセージメカニズムの使用方法
6575 ワード
一、メッセージメカニズムの作業手順
Handlerのワークフローは、非同期通信準備、メッセージ送信、メッセージループ、メッセージ処理の4つのステップに分けられます.
1.非同期通信準備:メインスレッドにプロセッサオブジェクト、メッセージキューオブジェクト、Handlerオブジェクトを作成し、LooperとMessageQueueは共にメインスレッドに属し、MessageQueueの作成後にLooperは自動的にメッセージループに入り、この時HandlerはメインスレッドのLooper、MessageQueneを自動的にバインドし、サブスレッドを起動する
2.メッセージエンキュー:作業サブスレッドはHandlerを通じてメッセージメッセージメッセージをメッセージキューMessageQueueに送信し、このメッセージ内容は作業スレッドによるUI操作である
3.メッセージ・ループ:Looperはバインドされたメッセージ・キューを巡回し、メッセージ・ループ中にメッセージ・キューが空の場合はスレッドがブロックされ、キューが空でない場合は、Lopperがメッセージ・キュー内のメッセージを1つずつ取り出し、メッセージを作成したHandlerに配布します.
4.メッセージ処理:処理者HandlerはLooperから送信されたメッセージを受け取り、メッセージに従ってUI操作を行う
二、Handler使用過程
Handlerの使用方法は、メッセージMessageをメッセージキューMessageQueueに送信方法によって異なり、Handlerの使用に分けられる.sendMessage()とHandlerを使用します.post()の2つの方法:
方式1:Handlerを用いる.sendMessage()は、新規Handlerサブクラスと匿名Handlerサブクラスの2つに分けられます.
1.新規Handlerサブクラス
(1)Handlerサブクラスをカスタマイズし、Handlerを継承し、handlerMessageメソッドを書き換えてUIを更新する操作、すなわち実行すべきUI操作を決定し、異なるスレッドから送られてきたメッセージに基づいて異なる操作を実行し、Messageのwhat属性に基づいて異なる情報を表示することができる
(2)メインスレッドにHandlerインスタンスを作成する
(3)マルチスレッドでMessageを通過する.obtain()は、必要なメッセージオブジェクトMessageを作成し、メッセージオブジェクトをインスタンス化し、whaとメッセージコンテンツobjの格納をメッセージ表示する.
(4)作業スレッドでHandlerを介してメッセージキューにメッセージを送信し、作業スレッドを開始し、作業スレッドはAsyncTask、Threadクラスの継承、Runnableの実装を用いて実現することができる
2.匿名Handlerサブクラス
(1)メインスレッドにおいて匿名内部クラスによりHandlerクラスオブジェクトを作成し,handlerMessage()を複写することによりUIを更新する操作を決定し,handleMessageにおいて異なるスレッドから送られてきたメッセージに基づいて異なるUI操作を実行する.
(2)作業サブスレッドに必要なメッセージオブジェクトMessageを作成する.obtain()は、メッセージオブジェクトをインスタンス化し、メッセージwhatの表示とメッセージ内容objの格納を行い、Handlerを介してメッセージをメッセージキューに送信する
(3)ワークスレッドにおいてHandlerによりメッセージをメッセージキューに送信する場合、マルチスレッドはAsyncTaskを採用し、Threadクラスを継承し、Runnableを実現し、ワークスレッドを開き、同時にHandlerを起動する
メインスレッドにHandlerを通過する.sendMessage()呼び出しプロシージャ
1.メインスレッド作成時にLooperを通過する.prepareMainLooper()とLooper.prepare()を使用して、必要なループオブジェクトとメッセージキューオブジェクトを作成します.
2.Looperを介してメッセージループを開始する.loop()でループ
3.Handlerインスタンスオブジェクトを作成し、Handlerを通過する.handler()はインスタンスを構築し、Handleの非パラメトリック構造関数では現在のLooperが取得されます.まずLooperを作成しないとエラーが発生し、Looperオブジェクトの指定を完了し、MessageQueueオブジェクトをバインドし、Handlerを通過します.handeMessage()はメッセージ処理とコールバックを行う.
4.メッセージオブジェクトを作成し、Message.obtain()でMessageオブジェクトを取得します.
5.Handlerを介してメッセージキューにメッセージを送信.sendMseeage()、Handler.enqueueMseeage()、MessageQueue.EnqueueMseeage()は、対応するメッセージキューオブジェクトを取得し、メッセージオブジェクトのtarget属性にhandlerの参照を付与し、最後にMessageQueueに送信する
6.メッセージの配信を行い、MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage()は、メッセージをデキューして対応するHandlerに配布し、最終的には複写されたHandlerMessageにコールバックして処理する.
方式2:Handlerを用いる.post()
(1)メインスレッドにHandlerインスタンスを作成する
(2)ワークスレッド内でメッセージをメッセージキューに送信ことにより、UIを更新する操作を確定するには、Handler.Post()にRunnableオブジェクトを入力してUI操作を実行
(3)作業スレッドを開き、同時にHandlerを起動し、マルチスレッドはAsyncTaskを採用し、Threadクラスを継承し、Runnableを実現できる
メインスレッドにHandlerを通過する.post()呼び出しプロセス
1.メインスレッド作成時にLooperを通過する.prepareMainLooper()とLooper.prepare()を使用して、必要なループオブジェクトとメッセージキューオブジェクトを作成します.
2.Looperを介してメッセージループを開始する.loop()でループ
3.Handlerインスタンスオブジェクトを作成し、Handlerを通過する.handler()はインスタンスを構築し、Handleの非パラメトリック構造関数では現在のLooperが取得されます.まずLooperを作成しないとエラーが発生し、Looperオブジェクトの指定を完了し、MessageQueueオブジェクトをバインドし、Handlerを通過します.handeMessage()メッセージ処理とコールバック
4.Handlerを介してメッセージキューにメッセージを送信する.post()、Runnable.run()、Handler.enqueueMseeage()、MessageQueue.EnqueueMseeage()は、内部で受信したRunnableオブジェクトをMessageオブジェクトにカプセル化し、対応するメッセージキューオブジェクトを取得し、メッセージオブジェクトのtarget属性をhandlerの参照に付与し、最後にMessage Queueに送信する
5.メッセージの配信を行い、MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage()は、メッセージをデキューして対応するHandlerに配布し、最終的には複写されたHandlerMessageにコールバックして処理する.
Handlerとその関連部分のソースコードについて知りたい場合は、Android:Handlerメッセージメカニズム(3)--Handlerソースコード分析
Handlerのワークフローは、非同期通信準備、メッセージ送信、メッセージループ、メッセージ処理の4つのステップに分けられます.
1.非同期通信準備:メインスレッドにプロセッサオブジェクト、メッセージキューオブジェクト、Handlerオブジェクトを作成し、LooperとMessageQueueは共にメインスレッドに属し、MessageQueueの作成後にLooperは自動的にメッセージループに入り、この時HandlerはメインスレッドのLooper、MessageQueneを自動的にバインドし、サブスレッドを起動する
2.メッセージエンキュー:作業サブスレッドはHandlerを通じてメッセージメッセージメッセージをメッセージキューMessageQueueに送信し、このメッセージ内容は作業スレッドによるUI操作である
3.メッセージ・ループ:Looperはバインドされたメッセージ・キューを巡回し、メッセージ・ループ中にメッセージ・キューが空の場合はスレッドがブロックされ、キューが空でない場合は、Lopperがメッセージ・キュー内のメッセージを1つずつ取り出し、メッセージを作成したHandlerに配布します.
4.メッセージ処理:処理者HandlerはLooperから送信されたメッセージを受け取り、メッセージに従ってUI操作を行う
二、Handler使用過程
Handlerの使用方法は、メッセージMessageをメッセージキューMessageQueueに送信方法によって異なり、Handlerの使用に分けられる.sendMessage()とHandlerを使用します.post()の2つの方法:
方式1:Handlerを用いる.sendMessage()は、新規Handlerサブクラスと匿名Handlerサブクラスの2つに分けられます.
1.新規Handlerサブクラス
(1)Handlerサブクラスをカスタマイズし、Handlerを継承し、handlerMessageメソッドを書き換えてUIを更新する操作、すなわち実行すべきUI操作を決定し、異なるスレッドから送られてきたメッセージに基づいて異なる操作を実行し、Messageのwhat属性に基づいて異なる情報を表示することができる
class mHandler extends Handler {
// handlerMessage() UI
@Override
public void handleMessage(Message msg) {
...// UI
}
}
(2)メインスレッドにHandlerインスタンスを作成する
private Handler mhandler = new mHandler();
(3)マルチスレッドでMessageを通過する.obtain()は、必要なメッセージオブジェクトMessageを作成し、メッセージオブジェクトをインスタンス化し、whaとメッセージコンテンツobjの格納をメッセージ表示する.
Message msg = Message.obtain(); //
msg.what = ; //
msg.obj = ; //
(4)作業スレッドでHandlerを介してメッセージキューにメッセージを送信し、作業スレッドを開始し、作業スレッドはAsyncTask、Threadクラスの継承、Runnableの実装を用いて実現することができる
// Thread
new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what = 1; //
msg.obj = "A"; //
// Handler
mHandler.sendMessage(msg);
}
}.start();
2.匿名Handlerサブクラス
(1)メインスレッドにおいて匿名内部クラスによりHandlerクラスオブジェクトを作成し,handlerMessage()を複写することによりUIを更新する操作を決定し,handleMessageにおいて異なるスレッドから送られてきたメッセージに基づいて異なるUI操作を実行する.
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
...// UI
}
};
(2)作業サブスレッドに必要なメッセージオブジェクトMessageを作成する.obtain()は、メッセージオブジェクトをインスタンス化し、メッセージwhatの表示とメッセージ内容objの格納を行い、Handlerを介してメッセージをメッセージキューに送信する
Message msg = Message.obtain(); //
msg.what = ; //
msg.obj = ; //
(3)ワークスレッドにおいてHandlerによりメッセージをメッセージキューに送信する場合、マルチスレッドはAsyncTaskを採用し、Threadクラスを継承し、Runnableを実現し、ワークスレッドを開き、同時にHandlerを起動する
new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what = 1; //
msg.obj = "A"; //
// Handler
mHandler.sendMessage(msg);
}
}.start();
メインスレッドにHandlerを通過する.sendMessage()呼び出しプロシージャ
1.メインスレッド作成時にLooperを通過する.prepareMainLooper()とLooper.prepare()を使用して、必要なループオブジェクトとメッセージキューオブジェクトを作成します.
2.Looperを介してメッセージループを開始する.loop()でループ
3.Handlerインスタンスオブジェクトを作成し、Handlerを通過する.handler()はインスタンスを構築し、Handleの非パラメトリック構造関数では現在のLooperが取得されます.まずLooperを作成しないとエラーが発生し、Looperオブジェクトの指定を完了し、MessageQueueオブジェクトをバインドし、Handlerを通過します.handeMessage()はメッセージ処理とコールバックを行う.
4.メッセージオブジェクトを作成し、Message.obtain()でMessageオブジェクトを取得します.
5.Handlerを介してメッセージキューにメッセージを送信.sendMseeage()、Handler.enqueueMseeage()、MessageQueue.EnqueueMseeage()は、対応するメッセージキューオブジェクトを取得し、メッセージオブジェクトのtarget属性にhandlerの参照を付与し、最後にMessageQueueに送信する
6.メッセージの配信を行い、MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage()は、メッセージをデキューして対応するHandlerに配布し、最終的には複写されたHandlerMessageにコールバックして処理する.
方式2:Handlerを用いる.post()
(1)メインスレッドにHandlerインスタンスを作成する
private Handler mhandler = new mHandler();
(2)ワークスレッド内でメッセージをメッセージキューに送信ことにより、UIを更新する操作を確定するには、Handler.Post()にRunnableオブジェクトを入力してUI操作を実行
mHandler.post(new Runnable() {
@Override
public void run() {
... // UI
}
});
(3)作業スレッドを開き、同時にHandlerを起動し、マルチスレッドはAsyncTaskを採用し、Threadクラスを継承し、Runnableを実現できる
new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// psot() , 1 Runnable
mHandler.post(new Runnable() {
@Override
public void run() {
// UI
mTextView.setText(" 1 UI ");
}
});
}
}.start();
メインスレッドにHandlerを通過する.post()呼び出しプロセス
1.メインスレッド作成時にLooperを通過する.prepareMainLooper()とLooper.prepare()を使用して、必要なループオブジェクトとメッセージキューオブジェクトを作成します.
2.Looperを介してメッセージループを開始する.loop()でループ
3.Handlerインスタンスオブジェクトを作成し、Handlerを通過する.handler()はインスタンスを構築し、Handleの非パラメトリック構造関数では現在のLooperが取得されます.まずLooperを作成しないとエラーが発生し、Looperオブジェクトの指定を完了し、MessageQueueオブジェクトをバインドし、Handlerを通過します.handeMessage()メッセージ処理とコールバック
4.Handlerを介してメッセージキューにメッセージを送信する.post()、Runnable.run()、Handler.enqueueMseeage()、MessageQueue.EnqueueMseeage()は、内部で受信したRunnableオブジェクトをMessageオブジェクトにカプセル化し、対応するメッセージキューオブジェクトを取得し、メッセージオブジェクトのtarget属性をhandlerの参照に付与し、最後にMessage Queueに送信する
5.メッセージの配信を行い、MessageQueue.next()、Handler.dispathMessage()、Handler.handlerMessage()は、メッセージをデキューして対応するHandlerに配布し、最終的には複写されたHandlerMessageにコールバックして処理する.
Handlerとその関連部分のソースコードについて知りたい場合は、Android:Handlerメッセージメカニズム(3)--Handlerソースコード分析