SurfaceView onMeasure() 没有通过调用 setMeasuredDimension() 设置测量尺寸

Tom*_*omi 6 android surfaceview onmeasure

我有一个 SurfaceView。我只是从另一个线程手动绘制它。

\n\n

它运行得很好。但平均运行 10-20 分钟后,我得到了这个异常:

\n\n
01-14 08:51:25.000    3740-3740/com.myPackage E/AndroidRuntime\xef\xb9\x95 FATAL EXCEPTION: main\n    java.lang.IllegalStateException: onMeasure() did not set the measured dimension by calling setMeasuredDimension()\n            at android.view.View.measure(View.java:15200)\n            at android.widget.RelativeLayout.measureChild(RelativeLayout.java:602)\n            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:415)\n            at android.view.View.measure(View.java:15195)\n            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)\n            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)\n            at android.view.View.measure(View.java:15195)\n            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)\n            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)\n            at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)\n            at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)\n            at android.view.View.measure(View.java:15195)\n            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)\n            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)\n            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2340)\n            at android.view.View.measure(View.java:15195)\n            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)\n            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1102)\n            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)\n            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)\n            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4216)\n            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)\n            at android.view.Choreographer.doCallbacks(Choreographer.java:555)\n            at android.view.Choreographer.doFrame(Choreographer.java:525)\n            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)\n            at android.os.Handler.handleCallback(Handler.java:615)\n            at android.os.Handler.dispatchMessage(Handler.java:92)\n            at android.os.Looper.loop(Looper.java:137)\n            at android.app.ActivityThread.main(ActivityThread.java:4813)\n            at java.lang.reflect.Method.invokeNative(Native Method)\n            at java.lang.reflect.Method.invoke(Method.java:511)\n            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)\n            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)\n            at dalvik.system.NativeStart.main(Native Method)\n
Run Code Online (Sandbox Code Playgroud)\n\n

Android 文档说: \n
测量视图及其内容以确定测量的宽度和测量的高度。此方法由measure(int, int) 调用,并应由子类重写,以提供对其内容的准确有效的测量。

\n\n

我认为谷歌的原始实现是这样的:

\n\n
@Override\n    protected void More ...onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);\n        int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);\n        setMeasuredDimension(width, height);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不知道我还应该在这里实施什么。

\n\n

我认为表面视图的大小永远不会改变。

\n\n

注意: \n
我的SurfaceView包含在RelativeLayout中。\n
异常由子进程调用,但它是一个视图(异常中的第3行)

\n\n

如果您知道如何解决这个恼人的错误,请帮助我。

\n\n

编辑: \n
在 Activity 的 onCreate 中,我从代码中设置了视图的大小(扩展形式 SurfaceView)

\n\n

回答评论: \n
这就是我为所需大小设置一些公共字段的方法:

\n\n
Parameters.initialize(getResources().getDisplayMetrics().widthPixels,\n                getResources().getDisplayMetrics().heightPixels);\n
Run Code Online (Sandbox Code Playgroud)\n\n

参数初始化:

\n\n
public static void initialize(int screenWidth, int screenHeight){\n    FIELD_WIDTH = screenWidth;\n    FIELD_HEIGHT = (int)(0.92f * screenHeight);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

MyView 是写在 xml 中的。\n
然后我在上面设置了一些东西:

\n\n
public class MyViewManager {\n    protected MyView mMyView;\n\n    public FieldPainterComp(MainActivity activity) {\n        super(activity);\n        initialize();\n    }\n\n    private void initialize(){\n        mMyView= (MyView) activity.findViewById(R.id.vMyView);\n        mMyView.getLayoutParams().height = Parameters.FIELD_HEIGHT;\n        mMyView.getLayoutParams().width = Parameters.FIELD_WIDTH;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

整个过程一开始就发生。

\n\n
android:screenOrientation="landscape"\n
Run Code Online (Sandbox Code Playgroud)\n\n

屏幕永远不会变暗。游戏正在运行,只是出现了异常。\n
我应该在某个地方调用测量吗?\n
我不明白为什么在很长一段时间后会发生这种情况

\n\n

其他一些必须与此相关的异常:

\n\n
01-19 11:53:39.812  29666-31881/com.mypackage V/GAV4\xef\xb9\x95 Thread[disconnect check,5,main]: Disconnecting due to inactivity\n01-19 11:53:39.812  29666-31881/com.mypackage V/GAV4\xef\xb9\x95 Thread[disconnect check,5,main]: Disconnected from service\n01-19 11:57:17.732  29666-29666/com.mypackage D/AndroidRuntime\xef\xb9\x95 Shutting down VM\n01-19 11:57:17.732  29666-29666/com.mypackage W/dalvikvm\xef\xb9\x95 threadid=1: thread exiting with uncaught exception (group=0x420face0)\n01-19 11:57:17.812  29666-29666/com.mypackage V/GAV4\xef\xb9\x95 Thread[main,5,main]: Tracking Exception: IllegalStateException (@View:measure:16533) {main}\n01-19 11:57:17.832  29666-29666/com.mypackage V/GAV4\xef\xb9\x95 Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete.\n01-19 12:19:27.982  29666-29670/com.mypackage I/dalvikvm\xef\xb9\x95 threadid=3: reacting to signal 3\n01-19 12:19:28.262  29666-29670/com.mypackage I/dalvikvm\xef\xb9\x95 Wrote stack traces to \'/data/anr/traces.txt\'\n01-19 12:19:32.452  29666-29666/com.mypackage A/libc\xef\xb9\x95 Fatal signal 6 (SIGABRT) at 0x0000025a (code=0), thread 29666 (ames.adaptation)\n
Run Code Online (Sandbox Code Playgroud)\n\n

GAV - 是 Google Analytics 的东西。

\n\n

我发起了另一个关于 ANR 的问题:ANR with 3threads - using locks

\n

Igo*_*sky 3

setMeasuredDimension()
Run Code Online (Sandbox Code Playgroud)

必须在 onMeasure() 方法内部调用。我遇到了类似的问题,逻辑未达到 setMeasuredDimension()。我解决了强制调用 setMeasuredDimension() 的问题,无论其前面的 if/else 语句是什么。