从非UI线程更新视图

ape*_*ite 5 multithreading android textview background-thread android-view

我对Android系统的工作方式感到困惑,尤其是在更新视图层次结构时。我们都知道,除了UI(Main)线程之外,我们不应从任何其他线程更新任何视图。当我们尝试这样做时,甚至Android系统也会引发异常。前几天,我试图在应用程序中实现显示视图的自定义进度。因此,我开始使用标准Java线程和处理程序组合。

当我能够从后台线程更新TextView时,我的发现使我感到惊讶。

new Thread(new Runnable() {

        @Override
        public void run() {
            mTextView.setText("I am " + Thread.currentThread().getName());
        }
    }).start();
Run Code Online (Sandbox Code Playgroud)

之后,我也尝试更新其他视图,效果很好。所以我尝试在后台线程中放置一个睡眠调用。

new Thread(new Runnable() {

        @Override
        public void run() {
            mTextView.setText("Thread : before sleep");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mTextView.setText("Thread : after sleep");
        }
    }).start();
Run Code Online (Sandbox Code Playgroud)

并按预期崩溃

android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。

然后,我尝试将setText()调用在sleep()调用之前和之后循环100次,1000次。当然,该应用程序每次都会崩溃,但我能够在textview上看到“睡眠前”文本。

所以我的问题是系统何时检测到某些非UI线程正在尝试更新视图当非UI线程中没有sleep()调用时为什么它不起作用

小智 -1

线程是UI线程的并行进程。当您尝试将 sleep 函数放入线程中时,线程的执行将停止。你的问题的答案就在问题本身之中。它说 - 只有创建视图层次结构的原始线程才能触摸它的视图。所以其他是两个线程,一个运行 ui 线程,另一个运行您创建的线程。当你调用 sleep 方法时。您的线程因与 ui 线程没有同步而停止执行。当您的线程尝试更改 textview 的文本时,两个线程都不同步。在睡眠之前,线程是同步的。睡眠后它们就不同步了。

  • 首先**线程不是进程**。暂时忘记 sleep() 调用,并在不睡眠的情况下尝试代码。该代码运行良好。这就是我的疑问所在,为什么android系统允许任何非UI线程更新视图。**它不会抛出异常**。顺便说一下,UI 线程和任何其他线程之间没有同步,无论您是否将其置于睡眠状态。 (3认同)
  • 你在开玩笑吧 ??我已经告诉过您(在您的最后一个回答中),我知道在为 Android 编写代码时要使用的所有多线程问题和相关模式。**请重新阅读我的问题。** (3认同)