Activity进程启动过程

Activity启动

Activity启动过程,下图应该是基于安装9或10,来自知乎张潮州。
在这里插入图片描述

需要注意的是ActivityStarter.startActivityUnchecked()方法:

  1. 计算启动的flags,首先计算flags是因为后面要根据flags选择启动的task,所以这一步是铺垫作用.这里读者可能会问为什么要计算,因为有些flags是冲突的,所以需要计算一下.
  2. 对于找到task的过程其实还包含一些特殊的activity模式和标志的处理,以及对activity复用的逻辑.可以复用的情况包含如下几种
    • LaunchSingleInstance
    • LaunchSingleTask
    • (singleTop|FLAG_ACTIVITY_SINGLE_TOP) && activity已经在已经在栈顶. 对于在栈顶这一条,如果指定了FLAG_ACTIVITY_NEW_TASK标志或者要启动的activity模式为LaunchSingleInstance或者 LaunchSingleTask的activity,又或者mOptions.getLaunchTaskId()指定了taskId(这个优先级要高于参数中指定的inTask).其实可以先把其他的符合复用条件的task放到栈顶.所以在复用之前还有根据条件将复用的task带到前台的环节. 对于activity复用后这些activity是不用启动的,之需要使他们可见可以返回了,还第5步有着类似的逻辑。
  3. 计算在哪个task中启动,这里可定是有四种种情况了
    1. 新创建一个task启动 (指定了FLAG_ACTIVITY_NEW_TASK标志,没有找到复用的task)。
    2. 在sourceRecord(也就是调用startActivity的activity),没有指定FLAG_ACTIVITY_NEW_TASK标志,并且sourceRecord不为空。
    3. 在指定的task中启动,一般是用于恢复task。
    4. 在当前焦点stack的topTask中启动 , 既没有FLAG_ACTIVITY_NEW_TASK,又没有指定task并且还没有mSourceRecord,这种情况根据注释说不会发生。
  4. 在锚定task并把它带到前台之后就可以启动activity了,使用 **mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions)**启动Activity。
  5. mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions) 使activity可见。

流程执行到ActivityStackSupervisor.startSpecificActivity()(安卓11的方法,上图中为安卓9方法startSpecificActivityLocked())方法时,判断Activity依附的进程是否存在,如果不存在通过AMS和Zygote进程通信,创建新进程。
在这里插入图片描述

查看Activity进程启动的打印的log和进程信息:
在这里插入图片描述

AMS进程的LRU列表

LRU列表(Least Recent Used List) — 最近最少使用的进程列表
经过AMS启动的每一个进程,都会加入到LRU列表中进行管理,这个LRU列表并不是随意排序或者说按加入的时间顺序进行排布的,而是有一定的逻辑进行计算,而后根据每个进程的实时动态状态进行改变的。
这个LRU列表的定义其实最终在ProcessList.java中,AMS中定义了一个processList的实体,并且在整个系统中只有一个这样的LRU列表专门用于管理AMS启动的所有进程。

LRU列表更新的逻辑如下:
首先LRU列表被分为三段,这三段分别放置带activity的进程,带service的进程以及其他以外的进程,使用两个标志mLruProcessServiceStart和mLruProcessActivityStart间隔开;其中,mLruProcessServiceStart表示带service的那一段进程的开始,如图所示,mLruProcessActivityStart表示带activity的那一段进程的开始,如图所示;这样区分是为了让LRU列表尾部的进程变得更重要,而头部就没这么重要;所以LRU列表中的进程重要性是从头到尾逐步递增。
在这里插入图片描述

updateLruProcessLocked

updateLruProcessLocked()方法在ActivityStack类中有3处可能被调用。

其中2次调用位置都处于ActivityStack类中的resumeTopActivityInnerLocked()方法:

  1. pausing: 通过home键返回;back键退出其中一个Activity(进程中还有其他Activity)。
  2. resume: 热启动Activity。

1次调用位于destroyActivityLocked()方法:

  • 通过back键退出进程最后一个Activity。

updateLruProcessLocked方法中存在对persist变量的判断,代表AndroidManifest.xml中属性android:persistent=“true”。

当在AndroidManifest.xml中将persistent属性设置为true时,那么该App就会具有如下两个特性:

  • 在系统刚起来的时候,该App也会被启动起来。
  • 该App被强制杀掉后,系统会重启该App。这种情况只针对系统内置的App,第三方安装的App不会被重启。

系统中存在此属性的应用:Nfc,Telephony,SystemUI等。

lmkd

updateOomAdjLocked :

  1. 当进程状态发生变化调用ActivityManagerService的updateOomAdjLocked()方法。
  2. 通过computeOomAdjLocked()方法倒序更新mLruProcesses所有进程状态。应用进程(ProcessRecord)的重要性由三个状态值表示:
    • adj:LMK杀进程的评分依据
    • procState:指示进程状态
    • schedGroup:指示进程调度策略
  3. applyOomAdjLocked将computeOomAdjLocked计算出的三个状态值应用起来。

从传递给lmkd的参数可以看出,lmkd的策略仅依赖于adj值。

ByteBuffer buf = ByteBuffer.allocate(4 * 4);
buf.putInt(LMK_PROCPRIO);
buf.putInt(pid);
buf.putInt(uid);
buf.putInt(amt);
writeLmkd(buf);

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值