专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
51好读  ›  专栏  ›  安卓开发精选

震惊!Android 子线程也能修改 UI?

安卓开发精选  · 公众号  · android  · 2021-01-17 19:40

正文

请到「今天看啥」查看全文



android:id = "@+id/rg_group"
android:layout_width = "match_parent"
android:layout_height = "30dp"
android:orientation = "horizontal"
app:layout_constraintTop_toTopOf = "parent" >
< RadioButton
android:id = "@+id/rb_test1"
android:layout_width = "0dp"
android:layout_height = "30dp"
android:layout_weight = "1"
android:text = "这是第一个radiobutton" />

< RadioButton
android:layout_width = "0dp"
android:layout_height = "30dp"
android:layout_weight = "1"
android:text = "这是第二个radiobutton" />

RadioGroup >
androidx.constraintlayout.widget.ConstraintLayout >

布局文件如上写完,然后写java代码:

    @Override
    protected void onResume() {
        super.onResume();
        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(5000);
                mRbTest1.setText("子线程修改UI");
            }
        }).start();
    }

run一下看下效果


竟然真的修改成功了!

这下就比较懵逼了,radioButton可以修改成功,难道radioButton做了什么特殊的处理么?随手去翻了一下radioButton的源码以及父类CompoundButton的源码,发现并没有特别之处。既然还是没找到原因,那么就debug源码看下具体的原因。

前面的流程一切正常,然后执行到checkForRelayout的时候就有问题了:


在checkForRelayout的方法里面,radioButton最终执行了invalidate方法直接return掉了。

一般我们会抛出Only the original thread that created a view hierarchy can touch its views. 这个异常是在checkThread方法里面,而checkThread是由于调用了requestLayout方法,这里没有执行requestLayout方法,自然不会崩溃。

  • 那么TextView是在什么地方执行的requestLayout呢?
  • 又是什么原因导致没有执行requestLayout方法呢?

我们先来看第一个问题:其实只要截图中的两个条件都没有进入就会执行requestLayout方法






请到「今天看啥」查看全文