Android,Thread+Handlerスレッドメッセージループ


Android,Thread+Handlerスレッドメッセージループ
andriodは、スレッド間の通信を満たすためにHandlerとLooperを提供する.例えば、サブスレッドがネットワークから画像をダウンロードし、ダウンロードが完了するとメインスレッドにメッセージが送信され、このメッセージはメインスレッドにバインドされたHandlerによって伝達される.Androidでは、ここのスレッドはメッセージループのあるスレッドとメッセージループのないスレッドに分かれており、メッセージループのあるスレッドには一般的にLooperという新しい概念があります.私たちのプライマリ・スレッド(UIスレッド)は、メッセージ・ループのスレッドです.このようなメッセージループのメカニズムに対して、私たちは新しいメカニズムHandleを導入して、私たちはメッセージループがあって、メッセージループの中に相応のメッセージを送信しなければなりません.カスタムメッセージは一般的に自分の対応する処理があって、メッセージの送信とクリア、メッセージの処理、これらをHandleの中にカプセル化して、HandleはLooperのあるスレッドに対してだけであることに注意してください.UIスレッドでもサブスレッドでも、Looperがあれば、メッセージキューに何かを追加して、対応する処理をすることができます.しかし、ここでもう一つ、UIに関するものであれば、サブスレッドに入れないことです.サブスレッドはUIを操作できないので、データやシステムなど他の非UIの操作しかできません.しかし、ここでもう一つ、UIに関するものであれば、サブスレッドに入れないことです.サブスレッドはUIを操作できないので、データやシステムなど他の非UIの操作しかできません.Handlerの作成は、このスレッドのメッセージ・キューにバインドされます.プライマリ・スレッドで作成された場合、メッセージ・キューを作成するためにコードを書く必要はありません.デフォルトのメッセージ・キューは、プライマリ・スレッドで作成されます.ただし、サブスレッドであれば、Handlerを作成する前にスレッドのメッセージキューを初期化する必要があります.次のコードに従います.
/**
 * 
 * @author allin.dev 
 * http://allin.cnblogs.com
 * 
 */
public class MainThread extends Activity {

	private static final String TAG = "MainThread";
	private Handler mMainHandler, mChildHandler;
	private TextView info;
	private Button msgBtn;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		info = (TextView) findViewById(R.id.info);
		msgBtn = (Button) findViewById(R.id.msgBtn);

		mMainHandler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				Log.i(TAG, "Got an incoming message from the child thread - "
						+ (String) msg.obj);
				//         
				info.setText((String) msg.obj);
			}

		};

		new ChildThread().start();
		
		
		msgBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				
				if (mChildHandler != null) {
					
					//        
					Message childMsg = mChildHandler.obtainMessage();
					childMsg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";
					mChildHandler.sendMessage(childMsg);
					
					Log.i(TAG, "Send a message to the child thread - " + (String)childMsg.obj);


				}
			}
		});

	}

	public void onDestroy() {
      super.onDestroy();
		Log.i(TAG, "Stop looping the child thread's message queue");

		mChildHandler.getLooper().quit();
	}

	class ChildThread extends Thread {

		private static final String CHILD_TAG = "ChildThread";

		public void run() {
			this.setName("ChildThread");

			//         ,   Handler    
			Looper.prepare();

			mChildHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					 Log.i(CHILD_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);


					try {

						//               
						sleep(100);

						Message toMain = mMainHandler.obtainMessage();
						toMain.obj = "This is " + this.getLooper().getThread().getName() +
									".  Did you send me \"" + (String)msg.obj + "\"?";

						mMainHandler.sendMessage(toMain);

						Log.i(CHILD_TAG, "Send a message to the main thread - " + (String)toMain.obj);

					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			};

			Log.i(CHILD_TAG, "Child handler is bound to - "+ mChildHandler.getLooper().getThread().getName());

			//           
			Looper.loop();
		}
	}
}

最後にサブスレッドを終了する操作が完了したら、quit()を呼び出してメッセージループキューを終了することを忘れないでください.mChildHandler.getLooper().quit();
ActivityとThread間の通信
   Acitivity                  

private static final int GUINOTIFIER = 0x1234;
                

public Calendar mCalendar;
public int mMinutes;
public int mHour;
public Handler mHandler;
private Thread mClockThread;

      Handler   Thread      

mHandler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case TestHandler.GUINOTIFIER://TestHandler Activity   
                        //  Handle                  ,     TextView      
                        mTextView .setText(mHour + " : " + mMinutes);
                        break;
                }
                super.handleMessage(msg);
            }
        };
          Thread

class LooperThread extends Thread {
        public void run() {
            super.run();
            try {
                do {//             
                    long time = System.currentTimeMillis();
                    final Calendar mCalendar = Calendar.getInstance();
                    mCalendar.setTimeInMillis(time);
                    mHour = mCalendar.get(Calendar.HOUR);
                    mMinutes = mCalendar.get(Calendar.MINUTE);
                    Thread.sleep(1000);
                    //            Handler
                    Message m = new Message();
                    m.what = Ex04_14.GUINOTIFIER;
                    Ex04_14.this.mHandler.sendMessage(m);
                } while (!LooperThread.interrupted());//              
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }