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

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

public void doLayout() { Runnable run = new Runnable() { public void run() { ViewerActivity.setContentView(R.layout.main); } }; handler.post(run); } private Handler handler;' 

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

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

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

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

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

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

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

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

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

如果您创建一个在UI thread外使用ViewUI thread那么它违反了第二个规则。

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

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