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
One of the most common errors that I found developing Android Apps is the
java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget
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:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/RootView">
...
Then, on the onDestroy()
method of your Activity, call the unbindDrawables()
method passing a reference to the parent View and then do a System.gc()
.
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
This unbindDrawables()
method explores the view tree recursively and:
I had got the java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget error at several times
1) When switching from app and back to the app some time later (Press home button and after browsing some url)
2) When login/logout to app frequently (within 10 seconds)
3) When switching the device horizontally/vertically
Finally I solved the error in following way
public void clearAllResources() {
// Set related variables null
System.gc();
Runtime.getRuntime().gc();
}
This is a practical answer, what I tried to avoid this problem at Run-time
Runtime.getRuntime().gc();
Calling Garbage Collector is a good Idea.
Add this line of code to Android Manifest File inside "application" tag: - android:largeHeap="true"
<application
android:theme="@android:style/Theme.NoTitleBar"
android:allowBackup="true"
android:largeHeap="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
First stop your application from crashing at run time by catching the OutOfMemory error at place which you think can generate this error as below:
try {
...
}
catch(OutOfMemoryError error) {
//decide what to do when there is not more memory available
}
You can fix the problem using opts.inSampleSize=2; or opts.inSampleSize=4
opts.inSampleSize=2; or opts.inSampleSize=4
BitmapFactory.Options opts = new BitmapFactory.Options();
// opts.inJustDecodeBounds = true;
opts.inSampleSize=2;
Bitmap myBitmap = BitmapFactory.decodeFile(st_imagepath,opts);
You are leaking resources (most likely the Drawable
object). Try the tools in What Android tools and methods work best to find memory/resource 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, eg 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, eg:
private void changeImage() {
if (mCurrentImage != null) {
mCurrentImage.recycle();
mCurrentImage = null;
System.gc();
}
mCurrentImage = getNewImage();
}
I made a couple of extensions to @hp.android's excellent answer:
android.R.id.content
.removeAllViews()
.System.gc()
in every onDestroy call (eg this answer ), so I've removed that. onDestroy
method that I call from onDestroy in all my custom Activity classes.Here's the code:
public static void onDestroy(Activity activity) {
View rootView = null;
try {
rootView = ((ViewGroup) activity.findViewById(android.R.id.content))
.getChildAt(0);
} catch (Exception e) {
Log.w("Cannot find root view to call unbindDrawables on",
activity);
}
if (rootView != null) {
Log.d("unbindDrawables", activity, rootView);
unbindDrawables(rootView);
}
}
/**
* Utility method to unbind drawables when an activity is destroyed. This
* ensures the drawables can be garbage collected.
*/
public static void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
try {
// AdapterView objects do not support the removeAllViews method
if (!(view instanceof AdapterView)) {
((ViewGroup) view).removeAllViews();
}
} catch (Exception e) {
Log.w("Ignore Exception in unbindDrawables", e);
}
}
}
Angel, there is a similar problem posted on StackOverflow here @ OutOfMemory exception when loading bitmap from external storage
And from there I inferenced SoftReference could also be an alternative for the solution .Do check the post it might prove helpful.
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
http://yekmer.posterous.com/android-memory-management
might be help this site.And you should free all reference .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.