小编典典

为什么不是UI线程的线程不能访问视图?

java

我知道没有线程可以访问当前视图,除非它是UI线程。我想知道为什么?哪个线程更改视图为什么很重要?是出于安全原因吗?这是我使用的解决方法:

        public void doLayout()
        {
            Runnable run = new Runnable()
            {
                public void run()
                {
                    ViewerActivity.setContentView(R.layout.main);
                }
            };

            handler.post(run);
        }

        private Handler handler;'

每当我想更改布局时,这样做都是一种痛苦。是否有其他解决方法?我了解异步任务,但从未找到一种使用它的好方法,它比我正在做的更好吗?所有相关的答案都适用!


阅读 269

收藏
2020-11-26

共1个答案

小编典典

是的,您的权利:为了安全起见,您不能在另一个线程上修改视图(这就是为什么将其称为UI线程)。它可以防止UI数据处于不一致状态,这可能会使您的应用程序崩溃,并且很难调试。因此,Android
API只是禁止这样做(这是个好主意)。这是大多数API中常见的UI模式。

您可以使用post()runOnUiThread()更新任何视图:

anyView.post(new Runnable() {
    public void run() {
        // do update here
    }
});

为什么是这种模式?
同步不是免费的。它影响性能。因此,更容易将对UI的修改保留在同一线程上。

如果我可以修改来自不同线程的数据,那会发生什么?
例如:线程A正在更改视图的颜色,线程B正在读取同一时间的颜色。由于多线程不能保证首先执行哪个指令,所以您可能会得到意想不到的结果。颜色0|0|0之前是黑色(),线程A要设置白色(255|255|255),然后将红色分量设置为255,线程B开始读取并获得整个颜色,然后线程A才有机会涂成红色(255|0|0)而不是黑色。

这是一个简单的示例,可能会影响视觉效果,但是如果某些真正重要的数据发生这种情况,则您的应用程序将崩溃,并且这种错误是如此令人讨厌且难以调试。有关多线程的知识很多,也许这个java教程是一个很好的起点。

2020-11-26