2011-10-09 28 views
2

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

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

      handler.post(run); 
     } 

     private Handler handler;' 

这是一种痛苦要做到这一点,每次我想改变布局。有没有不同的工作?我知道异步任务,我从来没有找到一个好的方法来使用它,比我在做什么好?所有相关的答案都很有趣!

+4

你应该阅读更多关于Java中锁定/同步(即当使用“同步”) - 一旦你明白,这将是显而易见的,为什么你有为了赴汤蹈火从单独的线程与UI线程进行交互。 –

+0

分离的原因是为了避免死锁。假设你可以自由修改任何线程的视图。假设你正在进行数据库调用。所以,你得到一个视图组件的处理程序,然后查询数据库,但数据库锁定并随后锁定当前线程。现在UI线程也将被锁定,因为您正在修改视图,并且必须等待它被释放才能安全继续。这会产生非常糟糕的程序,最终会导致比目前更多的锁定。 – methodin

+0

大多数用户界面,无论平台和语言如何,都只能访问主用户界面线程中的用户界面,推理通常是,制作线程安全用户界面非常困难,不值得花费精力,而且会导致非常严重的速度损失因为图形用户界面环境需要快速响应。 – nos

回答

12

是的你的权利:为了安全起见,你不能在另一个线程上修改视图(这就是为什么叫做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)代替黑色。

这是一个简单的例子,这将影响视觉效果,但如果这种情况发生了一些非常重要的数据应用程序会崩溃可怕和这样的错误是如此肮脏和难以调试。有很多要了解多线程,也许this java tutorial是一个很好的起点...

1

Android应用程序使用Single Thread Model和此线程负责将各种事件分派到UI元素。有两个规则,这单线程模型:

  1. 如果你创建一个线程,使用不要阻塞UI线程
  2. 不要从UI线程

外部访问Android的UI工具包View以外的UI thread则违反了第二条规则。

1

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

看看这个great wikipedia article about thread safety.

相关问题