【问题标题】:Restarting the app to free up heap memory重新启动应用程序以释放堆内存
【发布时间】:2013-10-11 08:05:34
【问题描述】:

在我的应用程序的特定时间点,我想完全重新启动应用程序,即终止与应用程序关联的进程,然后再次重新启动它。我想这样做以释放堆空间,因为我的应用程序包含很多位图。

我使用投票最高的this SO link 并创建了以下额外活动:

/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    // Do not forget to add it to AndroidManifest.xml
    // <activity android:name="your.package.name.MagicAppRestart"/>
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.exit(0);
    }
    public static void doRestart(Activity anyActivity) {
        anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
    }
}

并从另一个活动的所需位置将此活动称为MagicAppRestart.doRestart(this);

现在,问题是这在 android 2.3 上运行良好,但在 4.0 上,此代码仅退出应用程序但不要重新启动它

我做错了吗?是否存在适用于所有操作系统的解决方案?

另外,我已经尝试过以下代码,它会重新启动但不是进程,因此不会释放堆,所以它对我没有用:

Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

任何帮助表示赞赏!

编辑

我的应用中有 7 个活动,包括家庭活动。除家庭活动外,其他 6 个活动使用 ViewFlipper 和 5-8 个屏幕。

我在每个活动的onStop()onDestroy() 中都使用了 unbindDrawables(),但它只释放了一小部分内存。

因此,我希望完全重启应用进程。

编辑 2

我刚遇到这个:

此外,Android 改变了位图内存的分配方式。在 Android 3.0 之前,位图分配在本机内存中,Java 堆上只保留一个小的描述符;现在整个位图都是从 Java 堆中分配的。如果在内存中保存多个位图,这可能会导致 Java 堆很快用完。

我想这就是为什么我的方法适用于 2.3OS 设备而不是 4.0 OS 设备的原因。

【问题讨论】:

  • 你为什么要重启你的应用`,也许我们可以帮你做一个其他的方法
  • 如问题所述:释放堆空间,因为我的应用包含大量位图...
  • @GAMA 在销毁活动之前调用bitmap.recycle()。这会有所帮助
  • 如果您正在处理图像,也可以看看这个:developer.android.com/training/displaying-bitmaps/…
  • 我是从 xml 而不是从 java 类设置位图

标签: android android-intent application-restart


【解决方案1】:

您无法清除堆。阅读this 以获得更好的理解。

希望对你有帮助。

【讨论】:

  • 我已经测试过重新启动应用程序进程会清除应用程序,因为您完全杀死了正在运行的应用程序实例。
【解决方案2】:

你不应该打电话给System.exit(0)。退出并重新启动您的应用是个坏主意。

引用 https://groups.google.com/forum/#!topic/android-developers/G_D3pKnGLt0 的 Romain Guy 的话

(Romain Guy):用户没有,系统会自动处理。这就是活动生命周期(尤其是 onPause/onStop/onDestroy)的用途。 无论您做什么,都不要放置“退出”或“退出”应用程序按钮。它对 Android 的应用程序模型毫无用处。这也与核心应用程序的工作方式相反

要了解更多,请查看以下链接

Is quitting an application frowned upon?

您应该以不会遇到内存泄漏的方式编写代码。

管理位图内存

http://developer.android.com/training/displaying-bitmaps/manage-memory.html

还可以在内存管理上查看此链接

https://www.youtube.com/watch?v=_CruQY55HOk

编辑:

您可以在onResume 中绑定drawable,在onPause 中取消绑定。

【讨论】:

  • 我知道,System.exit(0) 不是 android 的最佳实践。但是如果需求需要这样的东西,我想我必须使用它。另外,我已经检查了内存泄漏。只是位图比较多。
  • @GAMA 你应该重新考虑你的设计,而不是使用System.exit(0)。不推荐。回收位图并检查第二个链接是否相同
  • @GAMA recycle 他们。重新启动您的应用不是一个好的解决方案。
  • 我是从 xml 而不是从 java 类设置位图
  • @GAMA 您可以在onPause 中删除它们并在不使用时回收它们
【解决方案3】:

试试这个。它对我有用:

Intent it = new Intent();

it.setComponent(new ComponentName(YourActivity.this.getPackageName(),YourActivity.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP);
YourActivity.this.getApplicationContext().startActivity(it);

【讨论】:

    【解决方案4】:

    根据一些人的建议,我认为在应用程序运行时通过代码退出/重新启动应用程序并不理想/建议。

    所以,我所做的是 - 设置一个标志来识别主页按钮点击,即应用程序的退出

    当时我打电话android.os.Process.killProcess(android.os.Process.myPid());彻底杀掉当前app的进程,避免app在后台运行。

    谢谢大家!

    【讨论】:

      【解决方案5】:

      how to programmatically "restart" android app? 中尝试 Oleg Koshkin 的最高投票答案。希望这会对你有所帮助。

      Intent mStartActivity = new Intent(context, StartActivity.class);
      int mPendingIntentId = 123456;
      PendingIntent mPendingIntent = PendingIntent.getActivity(context,  mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
      AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
      mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
      System.exit(0);
      

      【讨论】:

        猜你喜欢
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 2012-08-10
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        相关资源
        最近更新 更多