在子线程中new一个Handler为什么会报以下错误?
java.lang.RuntimeException:
Can't create handler inside thread that has not called Looper.prepare()
这是因为Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作,则调用线程也会堵塞。每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue)。如果在创建Handler时不指定与其绑定的Looper对象,系统默认会将当前线程的Looper绑定到该Handler上。
在主线程中,可以直接使用new Handler()创建Handler对象,其将自动与主线程的Looper对象绑定;在非主线程中直接这样创建Handler则会报错,因为Android系统默认情况下非主线程中没有开启Looper,而Handler对象必须绑定Looper对象。这种情况下,则有两种方法可以解决此问题:
方法1:需先在该线程中手动开启Looper(Looper.prepare()-->Looper.loop()),然后将其绑定到Handler对象上;
final Runnable runnable = new Runnable() {
@Override
public void run() {
//执行耗时操作
try {
Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
Thread.sleep(2000);
Log.e("bm", "执行完耗时操作了~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread() {
public void run() {
Looper.prepare();
new Handler().post(runnable);//在子线程中直接去new 一个handler
Looper.loop(); //这种情况下,Runnable对象是运行在子线程中的,可以进行联网操作,但是不能更新UI
}
}.start();
方法2:通过Looper.getMainLooper(),获得主线程的Looper,将其绑定到此Handler对象上。
final Runnable runnable = new Runnable() {
@Override
public void run() {
//执行耗时操作
try {
Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
Thread.sleep(2000);
Log.e("bm", "执行完耗时操作了~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread() {
public void run() {
new Handler(Looper.getMainLooper()).post(runnable);//在子线程中直接去new 一个handler
//这种情况下,Runnable对象是运行在主线程中的,不可以进行联网操作,但是可以更新UI
}
}.start();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)