Android 之 子线程中创建子线程以及子线程中toast 问题

来源:互联网 发布:神魔诛天战宠进阶数据 编辑:程序博客网 时间:2024/05/16 14:20


最近学习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());    }


以上。




0 0
原创粉丝点击