Android – surfaceview onmeasure() does not set the measured dimension by calling setmeasureddimension()
I have a surfaceview. I just draw it manually from another thread
It works well. But after an average of 10-20 minutes, I got this exception:
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)
Android documentation says: measure the view and its contents to determine the measured width and height. This method is called by measure (int, int) and should be overridden by subclasses to provide accurate and effective measurement of its contents
I think Google's original implementation is as follows:
@Override
protected void More ...onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
}
I don't know what I should do here
I don't think the size of the surface view will ever change
Note: my surfaceview is contained in relativelayout. This exception is called by a child, but it is a view (line 3 in the exception)
If you know how I can solve this annoying bug, please help me
Edit: in oncreate of activity, I set the size of the view (extended as surfaceview) from the code
Answer comment: This is how I set some public fields for the required size:
Parameters.initialize(getResources().getDisplayMetrics().widthPixels,
getResources().getDisplayMetrics().heightPixels);
Parameters.initialize:
public static void initialize(int screenWidth, int screenHeight){
FIELD_WIDTH = screenWidth;
FIELD_HEIGHT = (int)(0.92f * screenHeight);
}
MyView is written in XML. Then I set some things on it:
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;
}
}
The whole process happened at the beginning
android:screenOrientation="landscape"
The screen will never darken. The game is running, but the exception is coming. Should I call the measure somewhere? I don't understand why I will be happy after a long time
Other exceptions that must be related to this:
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 is Google Analytics
I posted another question about anr: anr with 3 threads – using locks
resolvent:
setMeasuredDimension()
It must be called inside the onmeasure () method. I have a similar problem. The logic does not reach setmeasureddimension (). I have solved the problem of forcibly calling setmeasureddimension (), no matter what the if / else statement is before it