我在 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/