问题: 直接在普通子线程中Toast会报错
错误关键: 1.普通的线程不能直接new一个handle,而Toast初始化代码中如下代码片:public class Toast {final Handler mHandler = new Handler();….}
2.为什么普通线程不能new一个Handle?
Handle类代码如下:
public Handler(){
mLooper = Looper.myLooper(); //普通线程新建的时候是没有Looper对象的,而主线程在初始化的时候就是有Looper队列,在这里会报错
if(mLooper == null){
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
}
Looper类中的代码片段:
public static final Looper myLooper(){
//这个方法是从当前线程的ThreadLocal中拿出设置的looper
return (Looper)sThreadLocal.get(); //最终根源是这:) 在普通线程中没有默认的Looper
}
处理方法: 1.为普通线程先设置一个消息循环, 使用 Looper.prepare()方法
public static final void prepare(){
if(sThreadLocal.get() != null){
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
2.进入消息循环查看消息 Looper.loop(); //为阻塞方法
public void onClick(View v){
new Thread(){
public void run(){
Looper.prepare(); //为该普通线程绑定一个Looper类
Toast.makeText(MainActivity.this, "Toast" , 1).show();
Looper.loop(); //进入loop循环中,查看消息队列
};
}.start();
}