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.

我该如何解决这个问题,为什么会这样

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

当您尝试从工作线程 Android 更新 UI 时抛出此异常。

确保从主线程更新 UI。

试试这个

 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();

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

我想推荐阅读这个网站runOnUiThread

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

如果您在 Kotlin 中需要它:

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

实际上 Android SDK 中有一个方法,您可以使用该方法在 UI 线程上 运行 invalidate() 而无需创建自己的 运行nable 或手动处理程序,请参阅官方文档 here.

public void postInvalidate ()

Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.

This method can be invoked from outside of the UI thread only when this View is attached to a window.