【问题标题】:Calling requestLayout from a separate thread从单独的线程调用 requestLayout
【发布时间】:2014-06-25 02:01:42
【问题描述】:

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

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

但是,事实证明,除了创建视图层次结构的原始线程之外,我不应该从任何其他线程调用 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?

我不确定这是否会使事情复杂化,但视图归运行输入法服务的所有对象所有。是的,它是一个基于 OpenGL 的 Android 键盘,但这是另一个可能与此问题不太相关的长篇故事。

【问题讨论】:

    标签: java android android-layout


    【解决方案1】:

    你需要post()Runnable对主线程进行任何与UI相关的操作。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多