2

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

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

            handler.post(run);
        }

        private Handler handler;'

每次我想更改布局时,这样做是一种痛苦。有不同的解决方法吗?我知道异步任务,但我从来没有找到使用它的好方法,它比我正在做的更好吗?所有相关的答案都是appriciated!

4

3 回答 3

15

是的,你的权利:为了安全起见,你不能在另一个线程上修改视图(这就是为什么它被称为 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 教程是一个很好的起点......

于 2011-10-09T01:45:30.960 回答
1

Android 应用程序使用单线程模型,该线程负责将各种事件分派给 UI 元素。这个单线程模型有两个规则:

  1. 不要阻塞 UI 线程
  2. 不要从 UI 线程外部访问 Android UI 工具包

如果您创建一个View在外部使用的线程,UI thread则它违反了第二条规则。

于 2011-10-09T02:12:11.573 回答
1

安全不是唯一的 UI 线程是唯一可以访问视图的线程。主要原因是视图背后的代码可能不是线程安全的。这意味着如果您有多个线程读取和写入公共变量,则无法保证数据不会损坏。

查看这篇关于线程安全的精彩维基百科文章。

于 2011-10-09T02:19:28.587 回答