Android中,在子线程使用Toast会报错?

在子线程中使用Toast抛出异常,提示错误显示:Can't create handler inside thread that has not cal…
关注者
101
被浏览
28,064
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

我觉得大家还应该再翻翻源码,就会发现,Toast.show并不是所谓的更新UI操作!(```逃)

Toast,Handler,分析为什么抛异常。

ActivityThread和ViewRootImpl分析到底什么叫子线程不能更新UI。


Toast本质上是一个window,跟activity是平级的,checkThread只是Activity维护的View树的行为。

Toast使用的无所谓是不是主线程Handler,吐司操作的是window,不属于checkThread抛主线程不能更新UI异常的管理范畴。它用Handler只是为了用队列和时间控制排队显示吐司。

即使是子线程,先Looper.prepare,再show吐司,再Looper.loop一样可以吐出来,只不过loop操作会阻塞这个线程,没人这么玩罢了,都是让Toast用主线程的Handler,这个是在ActivityThread里初始化的,本来就是阻塞处理所有的UI交互逻辑。

贴个代码吧还是~~


  new Thread(){
        public void run(){
          Looper.prepare();//给当前线程初始化Looper
          Toast.makeText(getApplicationContext(),"你猜我能不能弹出来~~",0).show();//Toast初始化的时候会new Handler();无参构造默认获取当前线程的Looper,如果没有prepare过,则抛出题主描述的异常。上一句代码初始化过了,就不会出错。
          Looper.loop();//这句执行,Toast排队show所依赖的Handler发出的消息就有人处理了,Toast就可以吐出来了。但是,这个Thread也阻塞这里了,因为loop()是个for (;;) ...
        }
  }.start();

不相信,我贴个图吧。测试环境api 24 ~~~



哎,有这功夫我给学生讲两道题多好~~~