是在从另一个线程调用更新Android用户界面的方法工作时出现的错误吗?

huangapple go评论73阅读模式
英文:

Is it a bug that calling methods that update Android UI from another thread works?

问题

我会给你两段代码。其中一段代码更新了子线程的用户界面。是的,你听得没错!

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".NbPlus">
    <TextView
        android:id="@+id/tv_test"
        android:text="TEXT"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:onClick="updateText"
        android:text="updateText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

Java 代码

public class NbPlus extends AppCompatActivity {
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_question);
        textView = findViewById(R.id.tv_test);
    }

    public void updateText(View view) {
        System.out.println("NB PLUS");
        new Thread(() -> textView.setText("Click Me!!!")).start();
    }
}

现在你可以运行这段代码,令人难以置信,它可以正常工作。如果你能解释为什么,请告诉我。

英文:

I will give you two pieces of code. One code updates the UI for the child thread. Yes, you heard me correctly!

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.NbPlus&quot;&gt;
    &lt;TextView
        android:id=&quot;@+id/tv_test&quot;
        android:text=&quot;TEXT&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;/&gt;
    &lt;Button
        android:onClick=&quot;updateText&quot;
        android:text=&quot;updateText&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;/&gt;
&lt;/LinearLayout&gt;

Java Code

public class NbPlus extends AppCompatActivity {
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_question);
        textView = findViewById(R.id.tv_test);
    }

    public void updateText(View view) {
        System.out.println(&quot;NB PLUS&quot;);
        new Thread(() -&gt; textView.setText(&quot;Click Me!!!&quot;)).start();
    }
}

Now you can run this code, which is incredible, it works correctly。
If you can explain why, please let me know。

答案1

得分: 1

这不是一个错误,但也不能保证会正常工作。 Android UI 工具包的 API 契约规定,对 UI 的更新必须在 UI 线程上完成(几乎总是与主线程相同)。 如果您违反了这个规则,例如通过调用 setText 来自另一个线程进行更新,那么发生的情况是未定义的。 它可能会工作,也可能没有任何效果,可能会立即崩溃,或者可能会在以后微妙地破坏事物并/或以后崩溃。

许多常常被错误调用在错误线程上的方法明确检查它们所在的线程,并在不是 UI 线程时崩溃。 这是一种旨在帮助开发人员更容易捕捉错误而不是任何修改 UI 的方法调用的必需行为。

英文:

This is not a bug, but it's not guaranteed to work, either. The Android UI toolkit API contract is that updates to the UI must be done on the UI thread (which is almost always the same as the main thread). What happens if you violate this rule by making an update from another thread, as you've done with your call to setText, is not defined. It may work, it may have no effect, it may crash immediately, or it may subtly break things and/or crash later.

Many methods that are commonly mistakenly called from the wrong thread explicitly check what thread they're on, and crash if it's not the UI thread. This is a feature intended to help developers more easily catch their mistakes, rather than a required behavior of any UI-modifying method call.

huangapple
  • 本文由 发表于 2020年8月13日 17:29:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63392123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定