为什么非ui线程无法修改视图属性?

时间:2016-04-27 04:31:06

标签: android multithreading uiview frameworks

在android中,如果我想在非ui线程中修改一些视图的属性(例如,用于TextView的setText),我必须编写如下代码:

 runOnUiThread(new Runnable(){
     textView.setText("Hello world");
 });

在c#中,我必须使用一个更复杂的委托。

那么为什么他们(框架)不能帮助我们在内部代码中执行这些操作,如下所示?

void setText(string text){
    if(isInMainThread()){
       //direct set text
    }else{
       post(new Runnable(){
         setText(text);
       });
    }
}

是否有任何理由与java thread stop方法类似,因为流程需要由编码器控制?

先谢谢,原谅我可怜的英语。

2 个答案:

答案 0 :(得分:1)

简短回答:由于Android的单线程架构,UI工具包不是线程安全的。

您可以在此处找到Android官方文档Android - Processes and Threads

的完整答案
  

当应用程序组件启动且应用程序没有运行任何其他组件时,Android系统会使用单个执行线程为应用程序启动新的Linux进程。默认情况下,同一应用程序的所有组件都在同一进程和线程(称为“主”线程)中运行。

此外:

  

Andoid UI工具包不是线程安全的。因此,您不能从工作线程操纵UI - 您必须从UI线程对您的用户界面进行所有操作。因此,Android的单线程模型只有两个规则:

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

答案 1 :(得分:1)

是的,我同意,创作者可以这样做,但可能来自Android架构的SOLID设计。

SOLID 是首字母缩略词,代表面向对象编程和设计的5个基本原则。在我看来,如果查看了调用哪个方法的线程,它将违反单一责任原则 - 应该查看是否负责检查使用了哪个线程?恕我直言,它不应该。我认为Android的创造者会同意我的意见;)

据我所知,在当前架构中,当您通过setText方法更改文本时,视图会发送其状态已更改的通知,并且操作系统负责重绘它,但说实话我仍然不知道有关如何处理的详细信息。

此外,通过这种方法,Android创建者试图鼓励应用程序开发人员考虑在哪个线程上调用哪些操作 - 例如大计算任务不应该是UI动画的一部分。