Androidプログラミングのメッセージ構造の実例分析


本論文の実例は、Androidプログラミングのメッセージ・メカニズムを説明する。皆さんに参考にしてあげます。具体的には以下の通りです。
一、キャラクターの説明
1.Looper:一つのスレッドはこのスレッド内のメッセージQueを管理するLooperオブジェクトを生成することができます。
2.Handler:Handlerオブジェクトを構築してLooperとコミュニケーションして、Message Queに新しいメッセージを送ることができます。または、Looperから送られてきたメッセージを受信する。
3.メッセージQueue:スレッドを格納するメッセージです。
4.スレッド:UI threadは通常main threadであり、Androidがプログラムを起動する時にMessage Queを作成します。
各スレッドには、LooperオブジェクトとMessage Queデータ構造が含まれています。あなたのアプリケーションでは、Handlerのサブクラスがループから送られたメッセージを受信しないように定義できます。
 
あなたのAndroidプログラムの中で、新しいスレッドが誕生したり、実行したりした場合、自動的にMessage Loopが作成されません。
AndroidにはGlobalのMessage Queデータ構造がありません。例えば、異なるAPK内のオブジェクトは、Massage Queを介してメッセージを交換することができません。
例えば、スレッドAのHandlerオブジェクトは、他のスレッドBやCなどにメッセージを送ることができ、スレッドAにメッセージを送ることができる。
スレッドAのメッセージは、スレッドAが所属するオブジェクトだけが処理できます。
Looper.myLooperを使用して、現在のスレッドのLooperオブジェクトを取得できます。
mHandler=new EeventHandlerを使用します。現在のスレッドのHandlerオブジェクトを作成するために使用できます。このうち、EeventHandlerは、既に実装されているHandlerのサブカテゴリである。
mHandler=new EeventHandlerを使用します。mainスレッドを処理するためのHandlerオブジェクトが誕生できます。このうち、EeventHandlerは、既に実装されているHandlerのサブカテゴリである。
 
このような説明はあまりにも似ているかもしれません。いくつかの実際的な例を挙げて説明します。
二、例を挙げる
1.スレッド内の異なるコンポーネント間のメッセージ伝達
Looperクラスは、特定のスレッド内のオブジェクト間のメッセージ交換を管理するために使用される。あなたのアプリケーションは多くのスレッドを生成することができます。一方、スレッドは、多くのコンポーネントを有してもよく、これらのコンポーネントの間ではしばしば相互にメッセージを交換する必要がある。このような必要があれば、スレッドの代わりにLooperオブジェクトを作成して、メッセージ交換の管理を担当してもいいです。Looperオブジェクトは、UIイベントやSystemイベントなどの各オブジェクトから送られてくるメッセージを格納するMessage Queデータ構造を確立する。
各スレッドには、LooperオブジェクトとMessage Queデータ構造が含まれています。あなたのアプリケーションでは、Handlerのサブクラスがループから送られたメッセージを受信しないように定義できます。
スレッドと異なるコンポーネント間のメッセージ転送:

public class Activity1 extends Activity implements OnClickListener{
  Button button = null;
  TextView text = null;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity1);
    button = (Button)findViewById(R.id.btn);
    button.setOnClickListener(this);
    text = (TextView)findViewById(R.id.content);
  }
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn:
      Looper looper = Looper.myLooper();//        looper
      MyHandler mHandler = new MyHandler(looper);//    handler    looper  
      //buton      mHandler     looper ,   messageQueue ,  mHandler       looper  
      mHandler.removeMessages(0);
      String msgStr = "         :    button";
      Message m = mHandler.obtainMessage(1, 1, 1, msgStr);//        
      mHandler.sendMessage(m);//    :       handleMessage       
      break;
    }
  }
  private class MyHandler extends Handler{
    public MyHandler(Looper looper){
      super(looper);
    }
    @Override
    public void handleMessage(Message msg) {//    
      text.setText(msg.obj.toString());
    }
  }
}

説明:
このプログラムが起動すると、現在のスレッドはループオブジェクトが誕生し、Message Queueデータ構造があります。
looper = Looper.myLooper ();
Looperカテゴリの静的myLooper関数を呼び出して、現在のスレッド内のLooperオブジェクトを取得します。
mHandler = new MyHandler (looper);
MyHandlerオブジェクトを構築してLooperとコミュニケーションをとる。Activityなどの対象はMyHandlerの対象でループにメッセージを送ることができます。そしてMessage Queに入れます。MyHandlerオブジェクトもListenerの役割を果たし、Looperオブジェクトから送られてきたメッセージを受信することができます。
Message m = mHandler.obtainMessage(1, 1, 1, obj);
まずMessageオブジェクトを作成し、オブジェクトにデータを保存します。
mHandler.sendMessage(m);
mHandlerオブジェクトを通してメッセージmをLooperに伝え、Message Queに入れる。
この時、Looperの対象はMessage Queにメッセージがあることを見て、それを放送します。mHandlerの対象はこのメッセージを受け取った時に、そのhandlee Message()関数を呼んで処理します。そこで「This my message!」を出力します。画面で、
キャラクター概要(回顧):
(1)UI threadは通常メーンthreadであり、Androidがプログラムを起動する時にMessage Queを作成します。
(2)もちろんLooperオブジェクトが必要です。このMessage Queを管理します。
(3)Handlerオブジェクトを構築して、Message Queに新しいメッセージを送ることができます。または、Looperから送られてきたメッセージを受信する。
(4)スレッドAのHandlerオブジェクトは、他のスレッドBやCなどからスレッドAにメッセージを送ることができます。
(5)スレッドAのメッセージは、スレッドAが属するオブジェクトだけが処理できます。
 
メインスレッドにメッセージを送る

public class Activity2 extends Activity implements OnClickListener{
  Button button = null;
  TextView text = null;
  MyHandler mHandler = null;
  Thread thread ;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity1);  
    button = (Button)findViewById(R.id.btn);
    button.setOnClickListener(this);
    text = (TextView)findViewById(R.id.content);
  }
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn:
      thread = new MyThread();
      thread.start();
      break;
    }   
  }  
  private class MyHandler extends Handler{    
    public MyHandler(Looper looper){
      super(looper);
    }
    @Override
    public void handleMessage(Message msg) {//    
      text.setText(msg.obj.toString());
    }   
  }
  private class MyThread extends Thread{
    @Override
    public void run() {
      Looper curLooper = Looper.myLooper();
      Looper mainLooper = Looper.getMainLooper();
      String msg ;
      if(curLooper==null){
       mHandler = new MyHandler(mainLooper);
       msg = "curLooper is null";
      }else{
       mHandler = new MyHandler(curLooper);
       msg = "This is curLooper";
      }
      mHandler.removeMessages(0);
      Message m = mHandler.obtainMessage(1, 1, 1, msg);
      mHandler.sendMessage(m);
    }
  }
}

説明:
Androidは、メインスレッドのために自動的にMessage Queを作成します。この子スレッドにはMessage Queが作られていません。だから、myLooperの値はnullで、main Looperはメインスレッドの中のLooperを指します。すると、実行は以下の通りになります。
mHandler = new MyHandler (mainLooper);
このmHandlerはメインスレッドに属します。
mHandler.sendMessage(m);
メインスレッドのメッセージメッセージQueにmメッセージを入れます。メーンLooperはMessage Queにメッセージがあると処理し、メインスレッドからmHandlerのhandler Message()に実行してメッセージを処理します。
ここで述べたように、皆さんのAndroidプログラムの設計に役に立ちます。