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

gsf*_*sfd 2 java android ui-thread

我知道没有线程可以访问当前视图,除非它是UI线程.我想知道为什么?为什么哪个线程正在改变视图?这是安全原因吗?这是我使用的工作:

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

            handler.post(run);
        }

        private Handler handler;'
Run Code Online (Sandbox Code Playgroud)

每次我想改变布局时,这样做都很痛苦.有不同的工作吗?我知道异步任务,我从来没有找到一个好的方法来使用它,它比我正在做的更好吗?所有相关的答案都很贴心!

Kni*_*edi 15

是的,你的权利:为了安全起见,你无法在另一个线程上修改视图(这就是为什么它被称为UI线程).它可以防止您将UI数据保留在一个不一致的状态,这可能会使您的应用程序崩溃并且很难调试.所以android API只是禁止这个(这是一个好主意).这是一种常见的UI模式,您可以在大多数API中找到它.

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

anyView.post(new Runnable() {
    public void run() {
        // do update here
    }
});
Run Code Online (Sandbox Code Playgroud)

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

如果我可以修改来自不同线程的数据会发生什么?
例如:线程A正在改变视图的颜色,线程B正在同时读取颜色.由于多线程无法保证首先执行哪条指令,因此可能会出现意外结果.颜色是black(0|0|0)之前,线程A想要设置white(255|255|255)并从设置红色组件开始255,线程B开始读取并获得整个颜色,然后线程A有机会完成并获得红色(255|0|0)而不是黑色.

这是一个影响视觉效果的简单示例,但如果某些非常重要的数据发生这种情况,您的应用程序将崩溃,并且这样的错误是如此令人讨厌且难以调试.关于多线程有很多东西需要学习,也许这个java教程是一个很好的起点......