您现在的位置是:网站首页> Android
Android Handler使用
- Android
- 2022-03-19
- 811人已阅读
在日常开发中,都避免不了进行网络请求,并更新View,由于Android中主线程不可以进行耗时操作,所以我们的网络请求只能放在子线程中,又由于在子线程中不能更新UI,所以我们就需要使用Handler切换到主线程并更新UI。
在介绍Handler使用之前,我们先了解以下两个问题。
1、为什么主线程不能进行耗时操作?
因为如果在主线程进行耗时操作,容易出现ANR,Application Not Responding,即应用无响应,当在一定的时间内,app无法响应时就会出现ANR,并弹出一个 对话框提示应用无响应,所以我们应该避免在主线程中进行耗时操作,当我们应用出现ANR时,会在
/data/anr/目录中生成traces.txt,我们可以通过这个文件查找错误信息。
2、为什么子线程中不能更新UI?
这是因为在子线程中更新UI不是线程安全的,在Android源码ViewRootImpl的checkThread方法中也对UI做了验证。
基于这两个问题,我们可以使用Handler来解决,接下来介绍Handler的基本使用。
Handler创建有两种,一个是在构造方法传CallBack,一个是重写类的 handleMessage() 方法。
private static final int MESSAGA_TEST_1 = 1;
/**
* 主线程有初始化好Looper,所以在主线程处理消息
*/
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MESSAGA_TEST_1:
if (tvTest != null) {
//传递消息obj
tvTest.setText((String) msg.obj);
}
break;
}
return false;
}
});
private Handler mHandler2 = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MESSAGA_TEST_1:
if (tvTest != null) {
//传递消息obj
tvTest.setText((String) msg.obj);
}
break;
}
}
};
接下来发送消息。
//创建Message
Message msg = Message.obtain();
msg.what = 0;
//创建Bundle
Bundle bundle = new Bundle();
bundle.putString("key","我是一笑消息");
//为Message设置Bundle数据
msg.setData(bundle);
//发送消息
handler.sendMessage(msg);
这个时候在handlerMessage方法中即可收到消息,获取Message中的数据,并更新UI了。是不是很简单。
线程
Thread m_Thread=new Thread(){
public void run(){
//耗时操作
...
//发消息更新界面,可以发送空消息
handler.sendEmptyMessage(0x1111);
}
}
m_Thread.start();