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 的 一种机制;方便使用!

更新 操作 ;否则报下面错误:


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

也可以使用 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 图示

                         

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

   6.4 总结和理解

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

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

7. Callback,HandlerThread 与 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一个交代!