Android如何在低位时释放内存,以及如何重新启动内存?

时间:2018-02-25 04:30:58

标签: android android-lifecycle

请注意以下词汇以避免混淆

1)当我说重新实施某项活动时,我的意思是Activity.onCreate(bundle)

2)当我说从头开始一项活动时,我的意思是Activity.onCreate(null)

(虽然我不确定它是否有所作为)对于本文的目的,请假设我感兴趣的Android应用程序都在同一任务中启动了它们的活动

Android如何从应用程序中释放内存?

让我们说我有一部电话。我一次使用很多应用程序。我对当前Snapchat应用程序感到厌倦。所以我按下主页按钮并打开Facebook请注意,我没有按后退按钮,因此Snapchat仍然存在于最近的应用概述中。

突然出于某种原因,手机内存非常低,需要从后台应用程序强行释放一些。

  • Android操作系统会杀死Snapchat某些活动以释放内存

  • Android操作系统会杀死Snapchat所有活动以释放内存

Android如何管理"杀死"应用

现在我想说我想回到Snapchat。我点击了概述按钮,然后从最近使用过的应用的滚动列表中选择Snapchat

  • Android操作系统是否会重新 {/ 1>

  • 活动
  • Android操作系统重新实施

  • 的所有活动
  • Android操作系统重新启动 活动Snapchat以及从头开始与初始启动器活动

1 个答案:

答案 0 :(得分:1)

TL; DRD:所有活动都被杀死。

ActivityManagerService似乎不再杀死任何东西(它只是强制GC调用并调度修剪事件)。

if (false) {
   // For now we won't do this; our memory trimming seems
   // to be good enough at this point that destroying
   // activities causes more harm than good.
   if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 
            && app != mHomeProcess && app != mPreviousProcess) {
       // Need to do this on its own message because the stack may not
       // be in a consistent state at this point.
       // For these apps we will also finish their activities
       // to help them free memory.
       mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
   }
 }

虽然当(如果)确实试图杀死某些内容时,它会杀死后台应用程序的整个过程(它只会调用kill -9 [PID])。并且因为默认情况下,所有活动都在一个PID下运行,所以当进程终止时它们都会被销毁。

同样适用于OOM和低记忆杀手 - 两者都是按照流程进行操作,并且不区分您的活动。

但请注意,有些人声称Android有时会在内存不足的情况下逐个杀死特定的活动。我没有在AOSP中找到任何证据。

==============
现在,关于恢复您的应用程序。我可能不是这里的专家,因为这与Android的“任务和后台堆栈系统”有关,这比他们的教程视频看起来更难。

操作从调用ActivityManager#moveTaskToFront(...)开始,最终导致我们ActivityManagerService#moveTaskToFrontLocked(...)

操作系统会尝试检索与您的应用关联的存储任务记录。如果您的应用程序被销毁,管理员将不得不转到ActivityStackSupervisor#restoreRecentTaskLocked(...),如果一切顺利,它会找到任务和后台堆栈并为任务中的每个活动执行此操作:

final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
   final ActivityRecord r = activities.get(activityNdx);
   mWindowManager.addAppToken(0, r.appToken, task.taskId, stack.mStackId,
     r.info.screenOrientation, r.fullscreen,
    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
       r.userId, r.info.configChanges, task.voiceSession != null,
      r.mLaunchTaskBehind);
}

当您开始一项新活动时,会调用相同的方法(WindowManager#addAppToken(...)),并附带注释:

// Here it is!  Now, if this is not yet visible to the
// user, then just add it without starting; it will
// get started when the user navigates back to it.

所以我的猜测是当操作系统恢复应用程序时,它会完全重新创建活动堆栈,但实际上只有最重要的活动才会重新启动。我想,设置一个实验很容易找出我是不是就在这里。

=======
还有一次更新:)是的,稍后调用这两种方法(ActivityStackSupervisor#resumeTopActivitiesLocked()ActivityStackSupervisor#resumeTopActivityLocked(...))。虽然我真的不希望他们为什么要在多个堆栈中恢复活动 - 正如我所说,我绝对不是这里的专家。