最近学习handler时,碰到一个自觉得有意思的问题,
有人说:“new Thread(run(){ //第1层子线程new Thread(run(//第2层子线程new Thread(run(){//第3层子线程}).start()) ).start()}).start()我想知道子线程套用子线程会有什么情况 我感觉后面的应该叫孙线程 曾孙线程”
关于这个问题 我们需要明白一个点,以上这种,看似是线程嵌套,其实,线程是没有嵌套关系的。线程与线程之间只有主副关系,一个子线程必须依赖一个主线程,而且主线程只有一个。当主线程关闭时,其下的所有子线程都会关闭。
而在子线程中toast 原理是和子线程中创建handler是差不多的。我们知道,普通线程是不能直接new一个handler的。
原因如下:
public Handler(){
…..
mLooper = Looper.myLooper();
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();
}
而事实上子线程只是一个普通的线程,其ThreadLoacl中没有设置过Looper,所以会抛出异常
如果需要在子线程中弹toast ,可如下解决:
new Thread(){
public void run() {
Log.i("log", "run");
Looper.prepare();
Toast.makeText(ActivityTestActivity.this, "toast", 1).show();
Looper.loop();
};
}.start();
就是手动加上 Looper.prepare()方法和Loop方法。
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());
}