Android为什么能在子线程中更新UI

Android为什么能在子线程中更新UI

刚学习Android开发的时候经常有需要在子线程里更新UI的操作,总是会遇到报错:Only the original thread that created a view hierarchy can touch its views.
“只有创建视图层次结构的原始线程才能触摸其视图。”

因为大部分的View创建都是在UI线程(主线程),所以我们都有一个共识:只有在UI线程中才能够更新UI
那为什么呢?

当我们遇到Only the original thread that created a view hierarchy can touch its views. 的时候,可以看到报错的路径是:at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7905)
说明ViewRootImpl这个类对当前线程是否为主线程进行了判断:

@Override
public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread();
            mLayoutRequested = true;
            scheduleTraversals();
        }
}

void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }

ViewRootImlcheckThread方法里,通过判断

mThread != Thread.currentThread()

如果当前没有在UI线程,就会抛出异常


那有没有在子线程中可以更新UI的操作呢?

这里放出一段代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.textView);
        new Thread(new Runnable() {
            @Override
            public void run() {
                tv.setText("子线程更新UI测试");
            }
        }).start();
    }

这样操作是可以改变TextView的Text属性并且没有报错的。
通过上面的了解可以推断,这个时候没有进入ViewRootImplcheckThread方法,逃过一劫,具体原因我们可以从源码入手。这里贴一下讲的很好的链接。

借鉴链接:https://www.jianshu.com/p/58c999d3ada7

结论:从源码分析可得知,ViewRootImpl对象是在onResume方法回调之后才创建,那么就说明了为什么在生命周期的onCreate方法里,甚至是onResume方法里都可以实现子线程更新UI,因为此时还没有创建ViewRootImpl对象,并不会进行是否为主线程的判断;

总结:

扫描二维码关注公众号,回复: 11212387 查看本文章
  • ViewRootImpl中有checkThread方法,如果当前线程不是UI线程会抛出异常
  • 子线程可以在ViewRootImpl还没有被创建之前更新UI;
  • ViewRootImpl在Activity启动流程中的OnResume()方法被创建
  • 访问UI是没有加对象锁的,在子线程环境下更新UI,会造成不可预期的风险;
  • 开发者更新UI一定要在主线程进行操作;

归根到底这个问题可以从Android的启动流程来分析,Android启动时,先进行OnCreate的回调,然后进行OnResume,这个时候ViewRootImpt还没有进行创建初始化,所以我们在OnCreate中在子线程更新UI是可行的。

原创文章 8 获赞 9 访问量 881

猜你喜欢

转载自blog.csdn.net/weixin_40303382/article/details/105410550