Android-Handler 总结(Handler 的使用 ,Looper , MessageQueue , HandlerThread )

1.回顾

   上篇学习了 Android 端实现 图片选择 ,压缩,上传 ,加载的 实例,包括服务器端实现;

2.重点

  (1)什么是Handler?

  (2)为什么使用 Handler?

  (3)更新UI 的 几种方式 ?

  (4)Looper , MessageQueue 与 Handler

  (5)Callback,HandlerThread 与 Handler 

  (6)主线程 发送 给 子线程实现 

3.什么是Handler?

    Android 给我们 提供 用来 更新 UI的 一套 机制,也是 一套 消息 处理的机制 ,我们可以发送 信息 ,也可以 通过 它处理消息;

   常用方法:

  sendMessgae()
  sendMessageDelayed()
  post(Runnable)
  postDelayed(Runnable,long)
<pre name="code" class="java">	//移除请求
		mHandler.removeCallbacks(new imageRunnable());


 


4.为什么使用 Handler?

    (1) 在设计的时候,Handler 就已经封装了一套 创建,传递,处理的机制,用于 更新 UI 的 一种机制;方便使用!

    (2) Android 不允许在 子线程里进行 Ui 的 更新 操作 ;否则报下面错误:

 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

    (3) Android 在4.0 及其以上版本 ,不允许 在 Ui线程(主线程)中 进行 网络请求;


5. 更新 UI的 几种方式?

  5.1 Thread + Handler + Message

     (1)Thread实现:也可以使用 Runnable 实现 开启子线程

	new Thread(){
			@Override
			public void run() {
				//执行 发送 数据到 handler
				
				//实现发送 
				Message message=mHandler.obtainMessage();
				message.obj="obtionMessage";
				message.sendToTarget();
				
				super.run();
			}
		}.start();;
  

   (2)Message 实现 :三种方式

         1)创建 Message对象,Handler发送

				Message message=new Message();
				message.obj="我是 message !!";
				mHandler.sendMessage(message);

        2)得到 Message 对象 ,Message发送

      

	Message message=mHandler.obtainMessage();
				message.obj="obtionMessage";
				message.sendToTarget();

       3)也可以得到Message对象 ,Handler 发送
	Message message=mHandler.obtainMessage();
				message.obj="obtionMessage";
				mHandler.sendMessage(message);

   (3) Handler 实现:进行 UI 操作

 

private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			// handler
			tv_show.setText(msg.toString());
		}

	};

   5.2 Runnable + Handler 

     (1)Runnable 实现

/**
	 * text Runnable
	 * 
	 * @author yuan
	 *
	 */
	class textRunnable implements Runnable {

		@Override
		public void run() {
			// 不允许 在 子线程里更新UI
			try {
				Thread.sleep(1000);
				tv_show.setText("不允许在子线程里修改UI");
				
				
				
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

   (2)Handler 实现
	private Handler handler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			
			
		}
	};

    (3)调用

	handler.post(new imageRunnable());
    
     或 延迟 请求:

		mHandler.postDelayed(new imageRunnable(), 1500);


     (4)移除调用

	//移除
		mHandler.removeCallbacks(new imageRunnable());


    5.3 runOnUiThread 直接 操作

    5.4 控件的 post 方式:Runnable+ post

  textview.post(Runnable);

6.Looper , MessageQueue 与 Handler

  6.1 Looper ?

      (1). 内部包含 消息队列 MessageQueue ,所有的消息 都 走 消息队列
      (2). Looper 方法 是 死循环 ,不断的从 MessageQueue取消息,如过有消息,就处理消息,没有就 阻塞;

  6.2 MessageQueue

      消息队列 ,可以添加 消息和处理消息

  6.3 图示

                         

   6.4 总结和理解

     (1)handler 负责发送消息和执行(负责发送 ,还负责接收),
     (2)Looper 负责接收handler消息 并直接把消息回传 给 handler自己 ,
     (3)MessageQueue 就是一个存储消息的容器;

     (4)理解:如果 仅仅使用的话,只需要记住 ,Handler 负责发送 ,还负责接收 ! Looper和MessageQueue其他不需    要 考虑就行了;

7. CallbackHandlerThread 与 Handler 

  7.1 Callback 和 Handler 

     (1)callback 可以 拦截 Message 消息 

     (2)看注释

/**
	 * 拦截消息
	 */
   private Callback callback=new Callback() {
	
	@Override
	public boolean handleMessage(Message msg) {
		// 消息发过来后 ,这里 比 handler 先 收到 消息;
		//可以实现 拦截消息 ,这里返回 false 则 handler 可以收到消息
		// 否则 返回true时 , 收不到 消息;
		return false;
	}
   };
	
   /**
    * callback 作为参数 拦截 消息
    */
	private Handler handler=new Handler(callback){
		@Override
		public void handleMessage(Message msg) {
			
			
		}
	};

   7.2 HandlerThread 和 Handler

         (1)HandlerThread 可以解决  多线程 并发的问题 ;

         (2)使用普通线程 还需要封装 ,比较麻烦;

8. 主线程 和 子线程 相互 发送 数据

  8.1 思路

         分别在 主线程和子线程中创建 handler 对象 ,相互发送就行了;

  8.2 练习HandlerThread

       (1)子线程 -> 主线程 发送 消息 (使用 主线程的 handler发送)

HandlerThread handlerThread=new HandlerThread("handlerThread");
		handlerThread.start();
		
		mhandler=new Handler(handlerThread.getLooper()){
			@Override
			public void handleMessage(Message msg) {
				//在这里 发送
				System.out.println(msg);
				
				//向主线程 发送消息
				Message message=new Message();
				message.obj=1993+"我是 子线程 发送过来的";
				zHandler.sendMessageDelayed(message,1000);
				
			}
		};
       

       (2)主线程 -> 子线程 发送 消息 (使用 子线程 handler 发送)

//主线程 zHandler
	private Handler zHandler=new Handler(){
		public void handleMessage(Message msg) {
			
			System.out.println(msg);
			
			//给子线程发送 消息
			Message message=new Message();
			message.obj="我是主线程发送来的";
			mhandler.sendMessageDelayed(message,1000);
			
		};
	};

9.总结

     Handler , 仅仅是使用的话,就不需要考虑 Looper 和 MessageQueue ; 若是理解的话,就需要 理解各个的职位;

    一句话总结:Handler 自己干自己的,但需要给Looper一个交代!


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值