Note that there are some explanatory texts on larger screens.

plurals
  1. POOutOfMemoryError when loading activities
    primarykey
    data
    text
    <p>I have a quite simple activity like this :</p> <pre><code>public class SurvivalActivity extends Activity { private static final String KEY_LAYOUT_ID = "SurvivalLayoutId"; int mLayoutId; private static final int[] mSurvivalLayouts = { R.layout.survival1, R.layout.survival2, R.layout.survival3, }; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent i = getIntent(); if (savedInstanceState != null &amp;&amp; savedInstanceState.containsKey(KEY_LAYOUT_ID)) { mLayoutId = savedInstanceState.getInt(KEY_LAYOUT_ID, 0); } else if (i != null) { mLayoutId = i.getIntExtra(KEY_LAYOUT_ID, 0); } else { mLayoutId = 0; } // Layout setContentView(mSurvivalLayouts[mLayoutId]); // Title Util.setTitleFont(this, findViewById(R.id.title)); // "Next" button final View nextButton = findViewById(R.id.survival_next); Util.setFont(this, nextButton, "Lobster.ttf"); nextButton.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { final Intent next = new Intent(SurvivalActivity.this, SurvivalActivity.class); next.putExtra(KEY_LAYOUT_ID, (mLayoutId + 1) % mSurvivalLayouts.length); startActivity(next); finish(); } }); } @Override protected void onSaveInstanceState(final Bundle outState) { outState.putInt(KEY_LAYOUT_ID, mLayoutId); } } </code></pre> <p>The two Util.<em>*</em> static methods just change the font of the <code>TextView</code>.</p> <p>All 3 layouts are rather simple, let me show you the first :</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"&gt; &lt;LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" &gt; &lt;TextView style="@style/Title" android:text="@string/surv1_title" /&gt; &lt;TextView style="@style/Content" android:text="@string/surv1_1" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_crafting" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_crafting_leg" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_hache" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_hache_leg" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_pioche" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_pioche_leg" /&gt; &lt;TextView style="@style/Content" android:text="@string/surv1_2" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_charbon" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_charbon_leg" /&gt; &lt;TextView style="@style/Content" android:text="@string/surv1_3" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_torch" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_torch_leg" /&gt; &lt;TextView style="@style/Content" android:text="@string/surv1_4" /&gt; &lt;ImageView style="@style/Picture" android:src="@drawable/surv_abri" /&gt; &lt;TextView style="@style/PicLegend" android:src="@string/surv_abri_leg" /&gt; &lt;TextView style="@style/Content" android:text="@string/surv1_5" /&gt; &lt;Button style="@style/SurvivalBoxNext" android:text="@string/surv1_next" /&gt; &lt;/LinearLayout&gt; &lt;/ScrollView&gt; </code></pre> <p>As you can see it's just several <code>TextView</code>s with <code>ImageView</code>s, and a <code>Button</code> that triggers the load of the next activity.</p> <p>I launch the app, it displays the first screen. I scroll down to the button, click, the second screen is displayed (with a hiccup). I scroll down to the button, click, and boom.</p> <pre><code>03-02 16:36:46.488 E/AndroidRuntime(10611): java.lang.RuntimeException: Unable to start activity ComponentInfo{net.bicou.myapp/net.bicou.myapp.SurvivalActivity}: android.view.InflateException: Binary XML file line #72: Error inflating class &lt;unknown&gt; 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread.access$600(ActivityThread.java:122) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.os.Handler.dispatchMessage(Handler.java:99) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.os.Looper.loop(Looper.java:137) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread.main(ActivityThread.java:4340) 03-02 16:36:46.488 E/AndroidRuntime(10611): at java.lang.reflect.Method.invokeNative(Native Method) 03-02 16:36:46.488 E/AndroidRuntime(10611): at java.lang.reflect.Method.invoke(Method.java:511) 03-02 16:36:46.488 E/AndroidRuntime(10611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 03-02 16:36:46.488 E/AndroidRuntime(10611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 03-02 16:36:46.488 E/AndroidRuntime(10611): at dalvik.system.NativeStart.main(Native Method) 03-02 16:36:46.488 E/AndroidRuntime(10611): Caused by: android.view.InflateException: Binary XML file line #72: Error inflating class &lt;unknown&gt; 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.createView(LayoutInflater.java:606) 03-02 16:36:46.488 E/AndroidRuntime(10611): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:653) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:678) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.rInflate(LayoutInflater.java:742) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 03-02 16:36:46.488 E/AndroidRuntime(10611): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.Activity.setContentView(Activity.java:1835) 03-02 16:36:46.488 E/AndroidRuntime(10611): at net.bicou.myapp.SurvivalActivity.onCreate(SurvivalActivity.java:34) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.Activity.performCreate(Activity.java:4465) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919) 03-02 16:36:46.488 E/AndroidRuntime(10611): ... 11 more 03-02 16:36:46.488 E/AndroidRuntime(10611): Caused by: java.lang.reflect.InvocationTargetException 03-02 16:36:46.488 E/AndroidRuntime(10611): at java.lang.reflect.Constructor.constructNative(Native Method) 03-02 16:36:46.488 E/AndroidRuntime(10611): at java.lang.reflect.Constructor.newInstance(Constructor.java:417) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.view.LayoutInflater.createView(LayoutInflater.java:586) 03-02 16:36:46.488 E/AndroidRuntime(10611): ... 25 more 03-02 16:36:46.488 E/AndroidRuntime(10611): Caused by: java.lang.OutOfMemoryError 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.Bitmap.nativeCreate(Native Method) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.Bitmap.createBitmap(Bitmap.java:605) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.Bitmap.createBitmap(Bitmap.java:551) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.content.res.Resources.loadDrawable(Resources.java:1937) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.widget.ImageView.&lt;init&gt;(ImageView.java:119) 03-02 16:36:46.488 E/AndroidRuntime(10611): at android.widget.ImageView.&lt;init&gt;(ImageView.java:109) 03-02 16:36:46.488 E/AndroidRuntime(10611): ... 28 more 03-02 16:36:46.520 W/ActivityManager( 211): Force finishing activity net.bicou.myapp/.SurvivalActivity </code></pre> <p>I don't understand :</p> <ol> <li>Why the previous activities are not freed to free up some space</li> <li>Why is my app taking up so much heap (<code>Grow heap (frag case) to 60.869MB for 3600016-byte allocation</code>)</li> <li>How can I do to display successively 3 activities containing each about 10 <code>TextView</code>s and 10 <code>ImageView</code>s</li> <li>If I did something wrong, because I can't see anything wrong in my code, but there is obviously something wrong.</li> </ol> <p>Thank you.</p> <p>Edit: picture sizes of the first activity:</p> <pre><code>-rw-r--r-- 1 bicou staff 167197 29 fév 16:42 surv_abri.jpg 600x377 px -rw-r--r-- 1 bicou staff 24658 29 fév 16:42 surv_charbon.png 559x277 px -rw-r--r-- 1 bicou staff 5285 29 fév 16:42 surv_crafting.png 214x121 px -rw-r--r-- 1 bicou staff 4190 29 fév 16:42 surv_hache.png 214x121 px -rw-r--r-- 1 bicou staff 3809 29 fév 16:42 surv_pioche.png 214x121 px -rw-r--r-- 1 bicou staff 2252 29 fév 16:42 surv_torch.png 215x121 px </code></pre> <p>Second activity:</p> <pre><code>-rw-r--r-- 1 bicou staff 3371 29 fév 16:42 surv_four.png 204x112 px -rw-r--r-- 1 bicou staff 5059 29 fév 16:42 surv_glass.png 215x122 px -rw-r--r-- 1 bicou staff 3176 29 fév 16:42 surv_malle.png 204x112 px -rw-r--r-- 1 bicou staff 2676 29 fév 16:42 surv_pelle.png 204x112 px -rw-r--r-- 1 bicou staff 167166 29 fév 16:42 surv_repere.png 528x331 px -rw-r--r-- 1 bicou staff 134706 29 fév 16:42 surv_sand.jpg 854x480 px </code></pre> <p>Third activity (crashing): </p> <pre><code>-rw-r--r-- 1 bicou staff 58919 29 fév 16:42 surv_1.jpg 600x377 px -rw-r--r-- 1 bicou staff 51144 29 fév 16:42 surv_2.jpg 600x377 px -rw-r--r-- 1 bicou staff 46917 29 fév 16:42 surv_3.jpg 600x377 px -rw-r--r-- 1 bicou staff 53226 29 fév 16:42 surv_4.jpg 600x377 px -rw-r--r-- 1 bicou staff 37787 29 fév 16:42 surv_5.jpg 600x377 px -rw-r--r-- 1 bicou staff 31050 29 fév 16:42 surv_6.jpg 600x377 px -rw-r--r-- 1 bicou staff 38389 29 fév 16:42 surv_7.jpg 600x377 px -rw-r--r-- 1 bicou staff 44471 29 fév 16:42 surv_8.jpg 600x377 px </code></pre> <p>And the Window background:</p> <pre><code>-rw-r--r-- 1 bicou staff 30857 29 fév 16:42 background_img.png </code></pre> <p>EDIT:</p> <p>OK — I tried inflating the views directly from code in order to see if I had a buggy image. Here's my activity code (only variables + <code>onCreate</code> as the rest is identical)</p> <pre><code>private static final int[] mTitles = { R.string.surv1_title, R.string.surv2_title, R.string.surv3_title }; private static final int[][] mTextViews = { { R.string.surv1_1, R.string.surv1_2, R.string.surv1_3, R.string.surv1_4, R.string.surv1_5 }, { R.string.surv2_1, R.string.surv2_2, R.string.surv2_3, R.string.surv2_4, R.string.surv2_5, R.string.surv2_6 }, { R.string.surv3_1, R.string.surv3_2, R.string.surv3_3 } }; private static final int[][] mImageViews = { { R.drawable.surv_pioche, R.drawable.surv_crafting, R.drawable.surv_hache, R.drawable.surv_charbon, R.drawable.surv_torch, R.drawable.surv_abri }, { R.drawable.surv_malle, R.drawable.surv_four, R.drawable.surv_pelle, R.drawable.surv_repere, R.drawable.surv_sand, R.drawable.surv_glass }, { R.drawable.surv_1, R.drawable.surv_2, R.drawable.surv_3, R.drawable.surv_4, R.drawable.surv_5, R.drawable.surv_6, R.drawable.surv_7, R.drawable.surv_8 }, }; private static final int[] mNextButtons = { R.string.surv1_next, R.string.surv2_next, R.string.surv3_next }; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent i = getIntent(); if (savedInstanceState != null &amp;&amp; savedInstanceState.containsKey(KEY_LAYOUT_ID)) { mLayoutId = savedInstanceState.getInt(KEY_LAYOUT_ID, 0); } else if (i != null) { mLayoutId = i.getIntExtra(KEY_LAYOUT_ID, 0); } else { mLayoutId = 0; } // Layout //setContentView(mSurvivalLayouts[mLayoutId]); LinearLayout ll; ScrollView sv; TextView tv; ImageView iv; Button b; sv = new ScrollView(this); sv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); ll.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); tv = new TextView(this); tv.setId(R.id.title); tv.setText(getString(mTitles[mLayoutId])); ll.addView(tv); for (final int textId: mTextViews[mLayoutId]) { tv = new TextView(this); tv.setText(getString(textId)); ll.addView(tv); } for (final int imgId: mImageViews[mLayoutId]) { L.i("Creating image: "+imgId); iv = new ImageView(this); iv.setImageResource(imgId); ll.addView(iv); } b = new Button(this); b.setText(getString(mNextButtons[mLayoutId])); b.setId(R.id.survival_next); ll.addView(b); sv.addView(ll); setContentView(sv); // Title Util.setTitleFont(this, findViewById(R.id.title)); // "Next" button final View nextButton = findViewById(R.id.survival_next); Util.setFont(this, nextButton, "Lobster.ttf"); nextButton.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { final Intent next = new Intent(SurvivalActivity.this, SurvivalActivity.class); next.putExtra(KEY_LAYOUT_ID, (mLayoutId + 1) % mSurvivalLayouts.length); startActivity(next); finish(); } }); } </code></pre> <p>As you can see I am just inflating the views directly, and <code>L.i</code> (which is an alias to <code>Log.i(TAG, ...)</code>) indicates what was the last ImageView inflated before any crash.</p> <p>I ran the app, saw the 1st activity, then the second, and as previously it crashes while loading the third one. The last ID I saw in the logcat was the last picture <code>R.drawable.surv_8</code>. This is a 630x377 jpeg file, 45 kiB.</p> <p>I tried to change the order of the views like this: </p> <pre><code>private static final int[][] mImageViews = { { R.drawable.surv_pioche, R.drawable.surv_crafting, R.drawable.surv_hache, R.drawable.surv_charbon, R.drawable.surv_torch, R.drawable.surv_abri }, { R.drawable.surv_malle, R.drawable.surv_four, R.drawable.surv_pelle, R.drawable.surv_repere, R.drawable.surv_sand, R.drawable.surv_glass }, { R.drawable.surv_8, R.drawable.surv_1, R.drawable.surv_2, R.drawable.surv_3, R.drawable.surv_4, R.drawable.surv_5, R.drawable.surv_6, R.drawable.surv_7, }, }; </code></pre> <p>So that surv_8 is first. The app is still crashing at the last picture, which is <code>R.drawable.surv_7</code>. So that is not an image issue.</p> <p>Then I removed one of the pictures out of <code>mImageViews[2]</code> so that I have only 7 pictures instead of 8. The app is working as expected: the activity loads, when I click the button I go to the next one, and on the last I go to the first. No crash.</p> <p>I can however tell that the activity 1 and 2 stay into memory. Indeed, have a look at the timings:</p> <pre><code>03-04 15:47:13.685 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +2s570ms 03-04 15:47:36.834 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +803ms 03-04 15:47:39.756 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +1s476ms 03-04 15:47:44.201 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +462ms 03-04 15:47:46.717 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +474ms 03-04 15:47:48.599 I/ActivityManager(17430): Displayed net.bicou.myapp/.SurvivalActivity: +474ms </code></pre> <p>400ms instead of 1.5-2.5 sec to load the activity.</p> <p>Why is this staying into memory?</p> <p>=> ** Do I need to manually free all pictures upon <code>onDestroy()</code> ? **</p> <p>=> What do you think about this: <a href="http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/" rel="nofollow">http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/</a><br> With this solution I could load like 10 bitmaps globally, and I would free some while loading another activity?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload