我知道没有线程可以访问当前视图,除非它是UI线程。我想知道为什么?为什么哪个线程正在改变视图?这是安全原因吗?这是我使用的工作:
public void doLayout()
{
Runnable run = new Runnable()
{
public void run()
{
ViewerActivity.setContentView(R.layout.main);
}
};
handler.post(run);
}
private Handler handler;'
每次我想改变布局时,这样做都很痛苦。有不同的工作吗?我知道异步任务,我从来没有找到一个好的方法来使用它,它比我正在做的更好吗?所有相关的答案都很贴心!
答案 0 :(得分:13)
是的,你的权利:为了安全起见,你不能修改另一个线程上的视图(这就是为什么它被称为UI线程)。它可以防止您将UI数据保留在一个不一致的状态,这可能会使您的应用程序崩溃并且很难调试。所以android API只是禁止这个(这是一个好主意)。这是一种常见的UI模式,您可以在大多数API中找到它。
您可以使用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
)而不是黑色之前获取整个颜色。
这是一个影响视觉效果的简单示例,但如果某些非常重要的数据发生这种情况,您的应用程序将崩溃,并且这样的错误是如此令人讨厌且难以调试。关于多线程有很多东西需要学习,也许this java tutorial是一个很好的起点......
答案 1 :(得分:1)
Android应用程序使用Single Thread Model,此线程负责将各种事件分派给UI元素。此单线程模型有两个规则:
如果您创建的线程在View
之外使用UI thread
,则会违反第二条规则。
答案 2 :(得分:1)
安全性不是唯一的UI线程是唯一可以访问Views的线程。主要原因是视图背后的代码可能不是线程安全的。这意味着如果您有多个线程读取和写入公共变量,则无法保证数据不会被破坏。