【问题标题】:Recreating activity cause Out Of Memory error重新创建活动导致内存不足错误
【发布时间】:2016-10-23 05:30:15
【问题描述】:

我正在尝试在运行时更改活动的样式。

但我在重新创建活动期间面临使用内存增加的问题。

为了改变风格,我定义了一些主题并在活动中为它们初始化int array

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

为了设置下一个主题,我在首选项中保存了主题 ID 并重新启动了活动。然后在onCreate 方法中,我从首选项设置主题:

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

这是我改变主题的方法:

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

在每次重新创建活动后,分配的内存堆增加了 0.1-0.2mb。因此,如果我多次更改应用程序主题,我会收到 Out Of Memory 错误。这是我的内存监视器:

memory monitor screen

仅在更改主题 1 分钟后,我将内存堆从 10 增加到 25 mb。 我尝试使用意图将recreate() 替换为重新启动活动,但结果是一样的:

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();
}

我还尝试了AndroidManifest 中的所有可用值launchMode。没有效果。 我将所有出现的“this”更改为“getApplicationContext()”。仅在 xml 文件中保留根布局。 这是similar problem。但是那里有两个活动。就我而言,如果我使用

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

activity 不会重新创建,因为它已经可见,并且不会调用 onCreate() 并且不会更改主题。 我也尝试在onDestroy() 中调用System.gc();,但内存使用量还是增加了。

这是我的styles.xml 文件的片段:

<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>

问题:

谁能告诉我我做错了什么以及如何防止增加内存使用量?或者也许有更好的方法可以在运行时改变应用的风格?

提前致谢!

【问题讨论】:

  • 在 Android 中泄露活动非常容易。你在使用任何 AsyncTasks 或 Handlers 吗?你有持有上下文的单例吗?
  • 如果您只是旋转设备而不调用主题切换代码,内存占用是否也会以同样的无限方式增长?此外,由于您要重新启动同一个 Activity,我想您只需使用 android:launchMode="singleTop" 就可以过关,而您不需要 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT。这有帮助吗?
  • 感谢您的快速回复! @CaseyB 我确实在我的代码中使用了 AsyncTasks 和 Handlers,但是为了测试,我评论了所有代码,只留下了 setThemesetContentView 方法。 @theFunkyEngineer 旋转设备会导致同样的情况。感谢您的回答,我尝试创建全新的测试项目。当我使用默认创建的 xml 布局时,重新创建活动内存后会增长,但几次后会返回到初始状态(大约 11mb)。当我将以前的 xml 布局放入新项目时 - 问题又回来了。所以我认为我的布局管理不好。我会用更多信息更新我的问题!

标签: android memory-management memory-leaks out-of-memory android-theme


【解决方案1】:

感谢大家的帮助!

在详细代码审查期间,我发现了 2 件事导致内存泄漏:

1) 在我的 xml 文件中,我使用了第 3 方视图 (AVLoadingIndicatorView),它不会删除 onDetachedFromWindow() 方法中的动画师。我还发现一些其他 3rd 方进度条在分离后没有清除动画。

2)我在适配器中有处理程序(这就是我的全部注意力不集中:()在破坏活动之前我不会停止和清除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多