根据Handler创建时所在的线程不同使用方式也有些不同
一、在主线程中
示例代码如下:
public class MainActivity extends AppCompatActivity {
private static final int MSG_1 = 1;
private static final int MSG_2 = 2;
Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//在主线程中处理所要进行的操作
switch (msg.what) {
case MSG_1:
//TODO 处理相关问题
Log.i("handler", "MSG_1,当前线程名称:" + Thread.currentThread().getName());
break;
case MSG_2:
//TODO 处理相关问题
Log.i("handler", "MSG_2,当前线程名称:" + Thread.currentThread().getName());
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendMessage();
postTask();
}
private void sendMessage() {
//从主线程中发送消息
handler.sendEmptyMessage(MSG_1);
new Thread(new Runnable() {
@Override
public void run() {
//从工作线程中发送消息
handler.sendEmptyMessage(MSG_2);
}
}).start();
}
private void postTask() {
//主线程中发送延时任务
handler.postDelayed(() -> {
Log.i("handler", "主线程中的postTask,当前线程名称:" + Thread.currentThread().getName());
}, 1000);
new Thread(() -> {
//工作线程中发送延时任务
handler.postDelayed(() -> {
Log.i("handler", "工作线程中的postTask,当前线程名称:" + Thread.currentThread().getName());
}, 1000);
}).start();
}
}
打印日志:
2021-01-07 11:50:25.433 5693-5693/com.example.behaviorapplication I/handler: MSG_1,当前线程名称:main
2021-01-07 11:50:25.433 5693-5693/com.example.behaviorapplication I/handler: MSG_2,当前线程名称:main
2021-01-07 11:50:26.400 5693-5693/com.example.behaviorapplication I/handler: 主线程中的postTask,当前线程名称:main
2021-01-07 11:50:26.400 5693-5693/com.example.behaviorapplication I/handler: 工作线程中的postTask,当前线程名称:main
在主线程中创建的Handler对象,不管是否从工作线程中发送消息或任务,所要处理的操作都是在主线程。
二、在工作线程中
示例代码如下:
public class MainActivity2 extends AppCompatActivity {
private static final int MSG_1 = 1;
private static final int MSG_2 = 2;
Handler threadHandler;
Handler mainHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (threadHandler == null) {
mainHandler.sendEmptyMessageDelayed(1, 1000);
} else {
sendMsg();
postTask();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initThreadHandler();
mainHandler.sendEmptyMessageDelayed(1, 1000);
}
/**
* 在工作线程中创建handler
*/
private void initThreadHandler() {
new Thread(() -> {
//创建当前线程的looper,必须在handler创建之前,否则报错
Looper.prepare();
Log.i("handler", "创建threadHandler,当前线程名称:" + Thread.currentThread().getName());
threadHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//在工作线程中处理所要进行的操作
switch (msg.what) {
case MSG_1:
//TODO 处理相关问题
Log.i("handler", "处理消息MSG_1,当前线程名称:" + Thread.currentThread().getName());
break;
case MSG_2:
//TODO 处理相关问题
Log.i("handler", "处理消息MSG_2,当前线程名称:" + Thread.currentThread().getName());
break;
}
}
};
//启动消息队列处理工作
Looper.loop();
}).start();
}
/**
* 发送消息
*/
private void sendMsg() {
//从主线程中发送消息
Log.i("handler", "发送MSG_1,当前线程名称:" + Thread.currentThread().getName());
threadHandler.sendEmptyMessage(MSG_1);
new Thread(new Runnable() {
@Override
public void run() {
//从工作线程中发送消息
Log.i("handler", "发送MSG_2,当前线程名称:" + Thread.currentThread().getName());
threadHandler.sendEmptyMessage(MSG_2);
}
}).start();
}
/**
* 开启延迟任务
*/
private void postTask() {
//主线程中发送延时任务
threadHandler.postDelayed(() -> {
Log.i("handler", "主线程中的postTask,当前线程名称:" + Thread.currentThread().getName());
}, 1000);
new Thread(() -> {
//工作线程中发送延时任务
threadHandler.postDelayed(() -> {
Log.i("handler", "工作线程中的postTask,当前线程名称:" + Thread.currentThread().getName());
}, 1000);
}).start();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (threadHandler != null) {
//手动停止looper,否则会引发内存泄漏
threadHandler.getLooper().quit();
}
}
注意Looper.loop();
是一个双层嵌套的死循环,需要手动的将Looper关闭(或者关闭对应的线程),否则很容易引发内存泄漏:
if (threadHandler != null) {
threadHandler.getLooper().quit();
}
打印日志:
2021-01-07 12:27:28.903 8206-8373/com.example.behaviorapplication I/handler: 创建threadHandler,当前线程名称:Thread-6
2021-01-07 12:27:29.904 8206-8206/com.example.behaviorapplication I/handler: 发送MSG_1,当前线程名称:main
2021-01-07 12:27:29.906 8206-8373/com.example.behaviorapplication I/handler: 处理消息MSG_1,当前线程名称:Thread-6
2021-01-07 12:27:29.907 8206-8379/com.example.behaviorapplication I/handler: 发送MSG_2,当前线程名称:Thread-8
2021-01-07 12:27:29.907 8206-8373/com.example.behaviorapplication I/handler: 处理消息MSG_2,当前线程名称:Thread-6
2021-01-07 12:27:30.909 8206-8373/com.example.behaviorapplication I/handler: 主线程中的postTask,当前线程名称:Thread-6
2021-01-07 12:27:30.909 8206-8373/com.example.behaviorapplication I/handler: 工作线程中的postTask,当前线程名称:Thread-6
在工作线程中创建的handler,不管从哪个线程中发送的消息或任务,所要处理的操作都是在创建handler的线程中。
我们在主线程中创建Handler时,没有处理Looper相关的代码,是因为在app启动主线程创建的过程中已经处理过了,可以在ActivityThread的public static void main(String[] args)
中查看相关代码。