我有一个SurfaceView。我只是从另一个线程手动绘制它。
它运行良好。但是平均运行 10-20 分钟后,我得到这个异常:
01-14 08:51:25.000 3740-3740/com.myPackage E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: onMeasure() did not set the measured dimension by calling setMeasuredDimension()
at android.view.View.measure(View.java:15200)
at android.widget.RelativeLayout.measureChild(RelativeLayout.java:602)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:415)
at android.view.View.measure(View.java:15195)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15195)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1390)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:681)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15195)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4823)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2340)
at android.view.View.measure(View.java:15195)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1850)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1102)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1275)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4216)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4813)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
at dalvik.system.NativeStart.main(Native Method)
安卓文档 说:测量
视图及其内容以确定测量的宽度和测量的高度。此方法由 measure(int, int) 调用,应由子类覆盖,以提供对其内容的准确有效的度量。
正如我认为谷歌的原始实现是这样的:
@Override
protected void More ...onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
}
我不知道我还应该在这里实现什么。
我认为表面视图的大小永远不会改变。
注意:
My SurfaceView 包含在 RelativeLayout 中。
异常由子项调用,但它是一个视图(异常中的第 3 行)
如果您知道如何解决这个烦人的错误,请帮助我。
编辑:
在 Activity 的 onCreate 中,我从代码中设置了视图(扩展表单 SurfaceView)的大小
安斯发誓评论:
这就是我为所需大小设置一些公共字段的方式:
Parameters.initialize(getResources().getDisplayMetrics().widthPixels,
getResources().getDisplayMetrics().heightPixels);
参数初始化:
public static void initialize(int screenWidth, int screenHeight){
FIELD_WIDTH = screenWidth;
FIELD_HEIGHT = (int)(0.92f * screenHeight);
}
MyView 是用 xml 编写的。
然后我在上面设置了一些东西:
public class MyViewManager {
protected MyView mMyView;
public FieldPainterComp(MainActivity activity) {
super(activity);
initialize();
}
private void initialize(){
mMyView= (MyView) activity.findViewById(R.id.vMyView);
mMyView.getLayoutParams().height = Parameters.FIELD_HEIGHT;
mMyView.getLayoutParams().width = Parameters.FIELD_WIDTH;
}
}
整个过程在开始时就发生了。
android:screenOrientation="landscape"
屏幕永远不会变暗。游戏正在运行,只是例外即将到来。
我应该在某个地方调用度量吗?
我不明白为什么过了很久才
必须与此相关的其他一些例外:
01-19 11:53:39.812 29666-31881/com.mypackage V/GAV4﹕ Thread[disconnect check,5,main]: Disconnecting due to inactivity
01-19 11:53:39.812 29666-31881/com.mypackage V/GAV4﹕ Thread[disconnect check,5,main]: Disconnected from service
01-19 11:57:17.732 29666-29666/com.mypackage D/AndroidRuntime﹕ Shutting down VM
01-19 11:57:17.732 29666-29666/com.mypackage W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x420face0)
01-19 11:57:17.812 29666-29666/com.mypackage V/GAV4﹕ Thread[main,5,main]: Tracking Exception: IllegalStateException (@View:measure:16533) {main}
01-19 11:57:17.832 29666-29666/com.mypackage V/GAV4﹕ Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete.
01-19 12:19:27.982 29666-29670/com.mypackage I/dalvikvm﹕ threadid=3: reacting to signal 3
01-19 12:19:28.262 29666-29670/com.mypackage I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
01-19 12:19:32.452 29666-29666/com.mypackage A/libc﹕ Fatal signal 6 (SIGABRT) at 0x0000025a (code=0), thread 29666 (ames.adaptation)
GAV - 是Google Analytics的东西。
我提出了另一个关于 ANR 的问题:具有 3 个线程的 ANR - 使用锁
setMeasuredDimension()
必须在 onMeasure() 方法中调用。 我遇到了类似的问题,逻辑没有达到setMeasuredDimension()。 我解决了强制调用 setMeasuredDimension() 的问题,无论它前面的 if/else 语句是什么。
你使用 Fragment,一开始就不写这一行
super.onCreate(savedInstanceState);
私有双纵横比 = 1.0;
私有布尔值称为重新创建 = true;
在测量中 ::-双局部比率 = 纵横比;
if (localRatio == 0.0) {
super.onMeasure(widthSpec, heightSpec);
} else {
int lockedWidth = MeasureSpec.getSize(widthSpec);
int lockedHeight = MeasureSpec.getSize(heightSpec);
if (lockedWidth == 0 && lockedHeight == 0) {
widthSpec = MeasureSpec.makeMeasureSpec((int) (basicWidth), MeasureSpec.AT_MOST);
heightSpec = MeasureSpec.makeMeasureSpec((int) (basicHeight), MeasureSpec.AT_MOST);
lockedWidth = MeasureSpec.getSize(widthSpec);
lockedHeight = MeasureSpec.getSize(heightSpec);
Log.i(TAG, "onMeasure: onMeasure");
callForRecreate();
}
// Get the padding of the border background.
int hPadding = getPaddingLeft() + getPaddingRight();
int vPadding = getPaddingTop() + getPaddingBottom();
// Resize the preview frame with correct aspect ratio.
lockedWidth -= hPadding;
lockedHeight -= vPadding;
if (lockedHeight > 0 && (lockedWidth > lockedHeight * localRatio)) {
lockedWidth = (int) (lockedHeight * localRatio + .5);
} else {
lockedHeight = (int) (lockedWidth / localRatio + .5);
}
// Add the padding of the border.
lockedWidth += hPadding;
lockedHeight += vPadding;
// Ask children to follow the new preview dimension.
super.onMeasure(MeasureSpec.makeMeasureSpec(lockedWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(lockedHeight, MeasureSpec.EXACTLY));
注意 :- callForRecreate() 因为您必须创建或重新启动活动
请务必致电super.onMeasure(widthMeasureSpec,heightMeasureSpec);例如@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec,heightMeasureSpec);然后你的代码}