1,hanlder 介绍
【1】介绍:
消息机制: handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消息,也可以处理消息
【2】handler的出现:
问题:ANR :application not response 应用无响应
当应用程序在主线程(main线程 ui线程)进行耗时(比如连接网络,拷贝大的数据 )的操作 一般5秒钟无响应就会报ANR为了避免出现ANR我们把耗时操作放在子线程去做,但是在子线程去更新UI会报错误
10-06 02:17:57.778: W/System.err(1596): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
只有在主线程才能更新UI,我们要开始用Handler了。
【3】hanlder 简单使用:
A,开启子线程处理耗时操作,使用handler传输数据:
// 实现按钮点击事件
public void click(View v) {
//创建一个子线程
new Thread() {
public void run() {
try {
if(xxxx){
// 把耗时的操作放到子线程里面 bitmap 是要传输的数据
Bitmap bitmap = BitmapFactory.decodeStream(in);
// 获取message对象,不去 new Message() 使用obtain方法是为了避免创建过多的对象
Message msg = Message.obtain();
// 数据塞进msg里面
msg.obj = bitmap;
// 给msg 加一个标识在handler 可以分类进行逻辑处理
msg.what = REQUESTSUCESS;
handler.sendMessage(msg);
}else {
Message msg = Message.obtain();
msg.what = REQUESTFAIL;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg = Message.obtain();
msg.what = REQUESTEXCEPTION;
handler.sendMessage(msg);
}
}
}.start();
B,创建handler成员变量,接收数据进行UI操作:
protected static final int REQUESTSUCESS = 0;
protected static final int REQUESTFAIL = 1;
protected static final int REQUESTEXCEPTION= 2;
//定义一个handler
private Handler handler = new Handler(){
//在这个方法里面处理消息
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case REQUESTSUCESS:
//[1]获取我们携带的数据
Bitmap bitmap = (Bitmap) msg.obj;
//[2]把btimap展示到imagview上
iv.setImageBitmap(bitmap);
break;
case REQUESTFAIL:
iv.setImageBitmap(null);
Toast.makeText(getApplicationContext(), "图片不存在", 1).show();
break;
case REQUESTEXCEPTION:
iv.setImageBitmap(null);
Toast.makeText(getApplicationContext(), "图服务器忙", 1).show();
break;
}
};
};
2,hanlder 原理:
【1】相关方法和类
looper类: 消息封装的载体。内部包含一个MessageQueue,所有的Handler发送的消息都走向这个消息队列
Looper.Loop方法,就是一个死循环,不断地从MessageQueue取消息,如果有消息就处理消息,没有消息就阻塞。
MessageQueue, 存储消息的容器是一个消息队列,添加消息,处理消息
A,looper.loop方法:
B,Message 类中的变量 msg.target 实际调用的是Handler
C,Handle处理系统消息
流程: handler.sendMessage(msg); 发送一个消息,消息进入MessageQueue 消息队列里,looper.loop无限循坏去监听MessageQueue,有消息就调用HandlerMessage,没有就阻塞。
总结: handler负责发送消息,Looper负责接收handler发送的消息,并把消息回传给handler自己。
遗留问题:不new message 用obtain方法 避免重复创建为对象导致内存溢出
对你们有帮助,请点赞支持一下。