繁体   English   中英

Android:只有创建视图层次结构的原始线程才能在调用 invalidate() 时触摸其视图

[英]Android: only the original thread that created a view hierarchy can touch its views when calling invalidate()

我正在尝试使用Movie对象播放 gif,它需要我调用invalidate()方法。 但是,每当我调用此方法时,都会出现以下错误:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我该如何解决这个问题以及为什么会发生

在 UI 线程上运行指定的操作。

我想推荐阅读这个网站runOnUiThread

runOnUiThread(new Runnable() {
  @Override
  public void run() {
    // call the invalidate()
  }
});

尝试这个

 final Handler handler=new Handler();
    new Thread(new Runnable() {
        @Override
        public void run() {
           //your code
            handler.post(new Runnable() {
                @Override
                public void run() {
                    invalidate()
                }
            });
        }
    }).start();

在 Android 中,只有主线程(也称为 UI 线程)可以更新视图。 这是因为在 Android 中,UI 工具包不是线程安全的。

当您尝试从工作线程更新 UI 时,Android 会引发此异常。

确保从主线程更新 UI。

如果您在 Kotlin 中需要它:

val handler = Handler(Looper.getMainLooper())
    handler.post({
        invalidate()
    })

实际上,Android SDK 中有一种方法可以用来在 UI 线程上运行 invalidate(),而无需手动创建自己的可运行或处理程序,请参阅此处的官方文档。

public void postInvalidate ()

导致在通过事件循环的后续循环中发生无效。 使用它可以使来自非 UI 线程的视图无效。

仅当此 View 附加到窗口时,才能从 UI 线程外部调用此方法。

我知道这是一个较老的问题,这里的答案已经有效,但我在使用Handler时遇到了问题,因为默认情况下 android studio 使用了错误的Handler对象。 我必须指定android.os.Handler即:

final android.os.Handler handler=new android.os.Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            do_your_ui_stuff_here
            }
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM