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);
//移除
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. 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一个交代!