java - 从单独的线程调用 requestLayout

标签 java android android-layout

我在 GLSurfaceView.Renderer 上有一个 OpenGL 游戏循环(更新+绘制),它在一个单独的线程上运行,而不是创建 GLSurfaceView 子类(包含渲染器)的线程。

有时,更新循环逻辑决定,“嗯,我们需要将 View 大小调整为一半大小”。然后调用 GLSurfaceView View 的 requestLayout,我的 onMeasure 函数将负责调整大小。

但是,事实证明我不应该从除创建 View 层次结构的原始线程之外的任何其他线程调用 requestLayout。我得到以下异常:

E/AndroidRuntime( 3693): FATAL EXCEPTION: GLThread 3424
E/AndroidRuntime( 3693): Process: com.android.gl2jni, PID: 3693
E/AndroidRuntime( 3693): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 3693):        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
E/AndroidRuntime( 3693):        at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
E/AndroidRuntime( 3693):        at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
E/AndroidRuntime( 3693):        at android.view.View.invalidate(View.java:10935)

<snip>

我尝试使用 postInvalidate,但我认为我需要的是更接近 postRequestLayout() 的东西。但是,只有 requestLayout()。

如何以某种方式触发 requestLayout?

我不确定这是否会使事情复杂化,但该 View 归运行输入法服务的任何人所有。是的,它是一个基于 OpenGL 的安卓键盘,但这是另一个长篇故事,可能与这个问题不太相关。

最佳答案

您需要 post() 一个 Runnable 并将任何与 UI 相关的操作发送到主线程。

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // do UI work
        yourview.requestLayout();
    }
});

请务必注意,您放入 run() 方法中的代码不会立即完成。它被添加到主线程处理的队列中,并将在未来“某个时候”执行。

关于java - 从单独的线程调用 requestLayout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24392835/

相关文章:

java - 在函数中读取和设置byte[]

android - 原始字符串,它们与转义字符串有何不同以及应该在哪里使用它们

java - 查找动态创建的 fragment 的内部 View

android - 相对布局未在父框架布局下调整大小

java - 函数中的不同参数

java - 迁移到 OpenJDK 11,哪个版本的 MySql 连接器与 java 11 兼容?

java - Jmeter中的响应处理

android - libgdx 游戏在某些设备上崩溃

android - 从 Google Play 获取付费应用的购买 token

android - myView.setLayoutParams(otherView.getLayoutParams());不工作,为什么?