I am trying to change the layout of my application from portrait to landscape and vice-versa. But if i do it frequently or more than once then at times my application crashes.. Below is the error log. Please suggest what can be done?
01-06 09:52:27.787: ERROR/dalvikvm-heap(17473): 1550532-byte external allocation too large for this process. 01-06 09:52:27.787: ERROR/dalvikvm(17473): Out of memory: Heap Size=6471KB, Allocated=4075KB, Bitmap Size=9564KB
01-06 09:52:27.787: ERROR/(17473): VM won't let us allocate 1550532 bytes
01-06 09:52:27.798: DEBUG/skia(17473): --- decoder->decode returned false
01-06 09:52:27.798: DEBUG/AndroidRuntime(17473): Shutting down VM
01-06 09:52:27.798: WARN/dalvikvm(17473): threadid=3: thread exiting with uncaught exception (group=0x4001e390)
01-06 09:52:27.807: ERROR/AndroidRuntime(17473): Uncaught handler: thread main exiting due to uncaught exception
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): java.lang.RuntimeException: Unable to start activity ComponentInfo{}: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3812)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.access$2300(ActivityThread.java:126)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1936)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Looper.loop(Looper.java:123)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.main(ActivityThread.java:4595)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invoke(Method.java:521)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at dalvik.system.NativeStart.main(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:513)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Activity.setContentView(Activity.java:1629)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at onCreate(Game.java:98)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 12 more
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.reflect.InvocationTargetException
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.widget.LinearLayout.<init>(LinearLayout.java:92)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.constructNative(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:500)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 22 more
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:464)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:340)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.Resources.loadDrawable(Resources.java:1705)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1850)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1799)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.ViewGroup.<init>(ViewGroup.java:296)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 26 more
I made a couple of extensions to @hp.android's excellent answer:
android.R.id.content
.removeAllViews()
.System.gc()
in every onDestroy call (e.g. this answer), so I've removed that.onDestroy
method that I call from onDestroy in all my custom Activity classes.Here's the code:
Add this line of code to Android Manifest File inside "application" tag: - android:largeHeap="true"
A 1550532 byte allocation sounds big. I'm guessing your layout has a reference to a bitmap image of some kind, a PNG perhaps? What are the dimensions of this PNG? If it is really big and you have more than a couple of them you might just not have enough memory to load them all at once.
Also if this is triggered by the rotation remember that your Activity is destroyed and recreated so you might need to be careful of static references. Take a look at this Google blog post. You'll need to be careful of keeping static references to things in your code which may result in leaks
Where does the image source come from? Do you have a 9MB image in your drawables folder?
There's a lot of discussion on issues with Android's native bitmap memory management, e.g. http://code.google.com/p/android/issues/detail?id=10821, http://code.google.com/p/android/issues/detail?id=8488, http://groups.google.com/group/android-developers/browse_thread/thread/ed57849ef705d421/11af8362d77a8cf4?lnk=raot . I've had good luck explicitly invoking recycle() and System.gc() every time I am finished with a bitmap, e.g.:
One of the most common errors that I found developing Android Apps is the
error. I found this error frequently on Activities using lots of bitmaps after changing orientation: the Activity is destroyed, created again and the layouts are “inflated” from the XML consuming the VM memory available for bitmaps.
Bitmaps on the previous Activity layout are not properly deallocated by the garbage collector because they have crossed references to their activity. After many experiments I found a quite good solution for this problem.
First, set the “id” attribute on the parent view of your XML layout:
Then, on the
onDestroy()
method of your Activity, call theunbindDrawables()
method passing a reference to the parent View and then do aSystem.gc()
.This
unbindDrawables()
method explores the view tree recursively and:You can fix the problem using
opts.inSampleSize=2; or opts.inSampleSize=4