Android - Handler、Looper、Thread、Message、Runnable

使用Handler可以实现将某些操作放在别的线程来执行。
private Handler mHandler;

public class MyHandler extends Handler{
    
    public MyHandler(Looper looper){
        super(looper);
    }
    
    public void handleMessage(Message msg){
        int what = msg.what;
        int arg1 = msg.arg1;
        int arg2 = msg.arg2;
        NetworkInfo info = (NetworkInfo)msg.obj;
        ......
    }
    
}

mHandler = new MyHandler(looper);   //注意这个looper

//以下是Handler的public方法:
final boolean postDelayed(Runnable r, long delayMillis)
final boolean sendEmptyMessage(int what)
final boolean sendEmptyMessageDelayed(int what, long delayMillis)
final void	 removeMessages(int what)

final boolean sendMessage(Message msg)
final boolean sendMessageAtFrontOfQueue(Message msg)
final boolean sendMessageDelayed(Message msg, long delayMillis)
//如果在sendMessageDelayed之后又sendMessage,那么后面的消息会先被处理


Message的建立有多种方式:

private static final int REPORT_STATUS = 1;

Message msg = new Message();
msg.what = REPORT_STATUS;
msg.arg1 = 3;
msg.obj = status;   //obj can be any type

Message msg = Message.obtain(Handler handler,int what);
Message msg = Message.obtain(Handler handler.int what,int arg1,int arg2,Object obj);

msg.setTarget(Handler handler);
msg.sendToTarget(); //发送消息,和mHandler.sendMessage(Message msg);作用一样。

Message msg = mHandler.obtainMessage(int what);
Message msg = mHandler.obtainMessage(int what,int arg1,int arg2,Object obj);

//所以有两种方式发送Message
mHandler.obtainMessage(REPORT_STATUS).sendToTarget();
mHandler.sendMessage(Message.obtain(mHandler.REPORT_STATUS));

可以将Runnable放到别的线程来执行:
mHandler.post(Runnable r);

Runnable r = new Runnable(){
  @Override
  public void run(){
    //code to be executed
  }
};

创建Handler时,最关键的是指定在哪个Looper里处理消息

我们希望在其它线程的消息循环里处理传递的消息,但是new Thread()时,
这个新的线程不存在消息队列,即没有Looper. 需要自己建立
	public class MyThread extends Thread{
		
		public Looper mLooper;
		
		public MyThread(){
			Log.d(TAG,"MyThread");
			start();            //在new MyThread时就start Thread
		}
		
		public void run(){
			
			Looper.prepare();   //初始化消息队列
			
			mLooper = Looper.myLooper();    //获取当前线程的Looper

			Looper.loop();		//启动消息循环机制
		}
						
	}
	
	private MyThread mThread = new MyThread();
	mHandler = new MyHandler(mThread.mLooper);
	//这样就可以在新建的Thead里处理消息了
以上代码比较麻烦,而且不太安全,需要等Thread run起来获取到looper之后,才能去创建MyHandler

Android提供了HandlerThread类,它替我们实现了Looper的建立过程。

	private Handler mHandler;
	private HandlerThread mHandlerThread;
	
	private static final int ENABLE = 1;
	private static final int START = 2;

    mHandlerThread = new HandlerThread("WorkHandler");  //name can be any
    mHandlerThread.start();
    mHandler = new MyHandler(mHandlerThread.getLooper());
    
    Log.d(TAG,"before test");
    
    mHandler.sendEmptyMessageDelayed(START, 1000);
    mHandler.sendEmptyMessage(ENABLE);

	public class MyHandler extends Handler{
		
		public MyHandler(Looper looper){
			super(looper);
		}
		
		@Override
		public void handleMessage(Message msg){
			int what = msg.what;
			
			switch(what){
			
			case ENABLE:
					Log.d(TAG,"handle Enable");
					break;
			case START:
					Log.d(TAG,"handle Start");
					break;				
			}
		}
		
	}
	
	D 06-24 18:07:57:986 15484 15484 before test
	D 06-24 18:07:57:986 15484 17678 before Enable
	D 06-24 18:07:58:996 15484 17678 before Start
	

从以上调试信息可以看到,消息是在新线程里处理的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值