HandlerThread
关于Handler的线程问题
每一个handler必须关联到线程的Looper,Looper用于管理消息队列(MessageQueue)
每一个Handler关联到的线程必须有已经启动的Looper,即已经调用过Looper.prepare()系列方法
Looper必须调用Looper.loop()方法才会开始工作
默认主线程(UI线程)已经存在调用过prepare()和loop()方法的Looper
在创建Handler对象时,如果没有指定Looepr,则使用创建时所在的线程的Looper
在创建Handler对象时,如果指定了Looper,则使用指定的Looper,
获取Looper对象的方式
Looper.myLooper()
public static Looper myLooper()
Looper.getMainLooper()
public synchronized static Looper getMainLooper()
实例:
HandlerThread
HandlerThread是一个线程类,该类的签名为:
public class HandlerThread extends Thread
HandlerThread是一个便利的带有Looper的线程类,它的Looper可被用于创建handler对象
在使用HandlerThread创建Handler对象之前,HandlerThread必须先调用start()方法
调用HandlerThread中的getLooper()方法,即可返回所在线程的Looper对象,用于创建Handler对象
public Looper getLooper()
实例:
在布局中加一个按钮即可:
andlerThread是一个带有Looper的线程类,只有在调用了start()方法以后,它才处于工作状态
在没有调用quit()方法之前,它的Looper会持续工作
在处理消息时,即使是使用Runnable对象,也只会调用run()方法,而并不会启动其它线程来完成任务
可以在Runnable中执行耗时操作,毕竟他会运行在子线程,但是,在耗时操作执行完之前,它并不能
处理新的消息,毕竟他只有一个线程
使用HandlerThread处理消息时效率相对于handler可能略低,但可以实现在子线程中处理来自线程的消息,
亦可分担主线程处理消息的压力。
每一个handler必须关联到线程的Looper,Looper用于管理消息队列(MessageQueue)
每一个Handler关联到的线程必须有已经启动的Looper,即已经调用过Looper.prepare()系列方法
Looper必须调用Looper.loop()方法才会开始工作
默认主线程(UI线程)已经存在调用过prepare()和loop()方法的Looper
在创建Handler对象时,如果没有指定Looepr,则使用创建时所在的线程的Looper
在创建Handler对象时,如果指定了Looper,则使用指定的Looper,
获取Looper对象的方式
Looper.myLooper()
public static Looper myLooper()
Looper.getMainLooper()
public synchronized static Looper getMainLooper()
实例:
布局中添加一个按钮即可:
package com.cn.hpu.handlerthread;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
private static final int MESSAGE_TEST = 9;
private Handler handler;
private Looper looper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out
.println("MAIN Thread ID = " + Thread.currentThread().getId());
// handler = new Handler(new InnerHandlerCallBack());
new WorkThread().start();
}
public void sendMessage(View view) {
handler = new Handler(looper,new InnerHandlerCallBack());
Message.obtain(handler, MESSAGE_TEST).sendToTarget();
}
private class InnerHandlerCallBack implements Handler.Callback {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("Thread ID = " + Thread.currentThread().getId());
return false;
}
}
private class WorkThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();
// handler = new Handler(new InnerHandlerCallBack());
handler = new Handler(Looper.getMainLooper(),
new InnerHandlerCallBack());
Looper.loop();
}
}
}
HandlerThread
HandlerThread是一个线程类,该类的签名为:
public class HandlerThread extends Thread
HandlerThread是一个便利的带有Looper的线程类,它的Looper可被用于创建handler对象
在使用HandlerThread创建Handler对象之前,HandlerThread必须先调用start()方法
调用HandlerThread中的getLooper()方法,即可返回所在线程的Looper对象,用于创建Handler对象
public Looper getLooper()
实例:
在布局中加一个按钮即可:
MainActivity:
public class MainActivity extends Activity {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandlerThread handlerThread = new HandlerThread("");
handlerThread.start();
handler = new Handler(handlerThread.getLooper(),new InnerHandlerCallback());
}
public void sendMessage(View view){
Message.obtain(handler).sendToTarget();
}
private class InnerHandlerCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println(" InnerHandlerCallback Thread ID = " + Thread.currentThread().getId());;
return false;
}
}
}
andlerThread是一个带有Looper的线程类,只有在调用了start()方法以后,它才处于工作状态
在没有调用quit()方法之前,它的Looper会持续工作
在处理消息时,即使是使用Runnable对象,也只会调用run()方法,而并不会启动其它线程来完成任务
可以在Runnable中执行耗时操作,毕竟他会运行在子线程,但是,在耗时操作执行完之前,它并不能
处理新的消息,毕竟他只有一个线程
使用HandlerThread处理消息时效率相对于handler可能略低,但可以实现在子线程中处理来自线程的消息,
亦可分担主线程处理消息的压力。
简单的使用HandlerThread实例:
布局同上,
public class MainActivity extends Activity {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HandlerThread handlerThread = new HandlerThread("");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
public void sendMessage(View view){
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread ID = " + Thread.currentThread().getId());
}
});
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理