【问题标题】:Why non-ui thread can not modify view properties?为什么非ui线程不能修改视图属性?
【发布时间】:2016-04-27 04:31:06
【问题描述】:

在 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线程停止方法被弃用的原因,因为流程需要由编码器控制?

提前感谢,并原谅我糟糕的英语。

【问题讨论】:

  • 所有与 UI 绘图相关的工作都在 1 个线程中完成,因此更改 UI 的代码应推送到该线程,否则会出现并发问题
  • 我同意。但是为什么框架不帮我们做这些额外的事情,他们可以检测到如果不在主线程中然后记录下来,然后在主线程中做这些事情。

标签: android multithreading uiview frameworks


【解决方案1】:

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

在这里你可以找到Android官方文档Android - Processes and Threads的完整答案

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

另外:

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

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

【讨论】:

  • 线程创建者理解为什么 android 是单线程的,他想知道为什么像 TextView.setText 这样的方法会负责检查该特定方法是否在 UI 线程上执行,如果不运行UI 线程中的代码。就像他在问题中发布的代码 sn-p 一样
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多