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属性に基づいて異なる情報を表示することができる
            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ソースコード分析