Search code examples
androidmemory-managementmemory-leaksout-of-memoryandroid-theme

Recreating activity cause Out Of Memory error


I'm trying to change activity's style in runtime.

But I faced with increasing used memory during recreating activity.

For changing style i define some themes and initialize int array for them inside activity:

private int themes[] = new int[]{R.style.AppThemeOrange, R.style.AppThemeTeal,...};

For setting next theme i saved theme id in preferences and restarted activity. Then inside onCreate method i set theme from preferences:

setTheme(PreferencesManager.getInstance().getAppTheme());

Here is my method for changing theme:

public void changeTheme() {
    PreferencesManager.getInstance().setAppTheme(themes[(getCurrentThemePos() + 1) % themes.length]);
    recreate();
}

After every recreating activity allocated memory heap increased by some value 0.1-0.2mb. So if i change app theme many times i'll get Out Of Memory error. Here is my memory monitor:

memory monitor screen

Only after 1 minute changing themes i increased memory heap from 10 to 25 mb. I tried to replace recreate() with relaunching activity using intent, but the result was the same:

public void changeTheme() {
    PreferencesManager.getInstance().setAppTheme(themes[(getCurrentThemePos() + 1) % themes.length]);
    Intent intent = new Intent(getApplicationContext(), UsersActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    finish();
}

Also i tried all available values launchMode in AndroidManifest. No effect. I changed all occurences of "this" to "getApplicationContext()". Left only root layout in xml file. Here is a similar problem. But there are two activities there. In my case if i use

Intent i = new Intent(getApplicationContext(), UsersActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);

activity doesn't recreates, because it is already visible, and onCreate() isn't called and theme isn't changed. Also i tried to call System.gc(); in onDestroy(), but memory usage increased anyway.

Here is fragment of my styles.xml file:

<style name="ChangebleTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
    <item name="android:editTextStyle">@style/EditTextStyle</item>
    <item name="editTextStyle">@style/EditTextStyle</item>
    <item name="android:buttonStyle">@style/ButtonStyle</item>
    <item name="buttonStyle">@style/ButtonStyle</item>
    <item name="android:checkboxStyle">@style/CheckboxStyle</item>
    <item name="checkboxStyle">@style/CheckboxStyle</item>
    <item name="switchStyle">@style/SwitchStyle</item>
    <item name="alertDialogProTheme">@style/Theme.AlertDialogPro.Material.Light</item>
</style>

<style name="AppThemeOrange" parent="ChangebleTheme">
    <item name="main_theme_color">@color/colorAccentOrange</item>
    <item name="main_theme_color_dark">@color/colorAccentDarkOrange</item>
    <item name="colorAccent">@color/colorAccentOrange</item>
    <item name="colorPrimaryDark">@color/colorAccentDarkOrange</item>
    <item name="android:navigationBarColor">@color/colorAccentOrange</item>
    <item name="ab_divider_style">@style/AppThemeOrange.ActionBarDivider</item>
</style>

<style name="AppThemeTeal" parent="ChangebleTheme">
    <item name="main_theme_color">@color/colorAccentTeal</item>
    <item name="main_theme_color_dark">@color/colorAccentDarkTeal</item>
    <item name="colorAccent">@color/colorAccentTeal</item>
    <item name="colorPrimaryDark">@color/colorAccentDarkTeal</item>
    <item name="android:navigationBarColor">@color/colorAccentTeal</item>
    <item name="ab_divider_style">@style/AppThemeTeal.ActionBarDivider</item>
</style>

QUESTION:

Can somebody show me what i'm doing wrong and how can i prevent increasing memory usage? Or maybe there is better way to change style of app in runtime?

Thanks in advance!


Solution

  • Thanks all for your help!

    During detail code review i found 2 things that caused memory leak:

    1) In my xml file i used 3rd party view (AVLoadingIndicatorView) wich doesn't remove animators in onDetachedFromWindow() method. Also i found that some another 3rd party progress bars don't clear animations after detaching.

    2) I had handler inside adapter ( that's all my inattention :( ) which i don't stop and clear before destroying activity.