android app启动过程分析,Android app启动流程

activity的启动从ActivityManagerService最终会转到 frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java 里面的startActivityMayWait中来。

final int startActivityMayWait(IApplicationThread caller, int callingUid, ...) {

if (intent != null && intent.hasFileDescriptors()) {

throw new IllegalArgumentException("File descriptors passed in Intent");

}

boolean componentSpecified = intent.getComponent() != null;

final Intent ephemeralIntent = new Intent(intent);

intent = new Intent(intent);

ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

if (rInfo == null) {

UserInfo userInfo = mSupervisor.getUserInfo(userId);

if (userInfo != null && userInfo.isManagedProfile()) {

UserManager userManager = UserManager.get(mService.mContext);

boolean profileLockedAndParentUnlockingOrUnlocked = false;

long token = Binder.clearCallingIdentity();

try {

UserInfo parent = userManager.getProfileParent(userId);

profileLockedAndParentUnlockingOrUnlocked = (parent != null)

&& userManager.isUserUnlockingOrUnlocked(parent.id)

&& !userManager.isUserUnlockingOrUnlocked(userId);

} finally {

Binder.restoreCallingIdentity(token);

}

if (profileLockedAndParentUnlockingOrUnlocked) {

rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,

PackageManager.MATCH_DIRECT_BOOT_AWARE

| PackageManager.MATCH_DIRECT_BOOT_UNAWARE);

}

}

}

ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

ActivityOptions options = ActivityOptions.fromBundle(bOptions);

ActivityStackSupervisor.ActivityContainer container =

(ActivityStackSupervisor.ActivityContainer)iContainer;

synchronized (mService) {

if (container != null && container.mParentActivity != null &&

container.mParentActivity.state != RESUMED) {

// Cannot start a child activity if the parent is not resumed.

return ActivityManager.START_CANCELED;

}

final int realCallingPid = Binder.getCallingPid();

final int realCallingUid = Binder.getCallingUid();

int callingPid;

if (callingUid >= 0) {

callingPid = -1;

} else if (caller == null) {

callingPid = realCallingPid;

callingUid = realCallingUid;

} else {

callingPid = callingUid = -1;

}

final ActivityStack stack;

if (container == null || container.mStack.isOnHomeDisplay()) {

stack = mSupervisor.mFocusedStack;

} else {

stack = container.mStack;

}

stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;

final long origId = Binder.clearCallingIdentity();

final ActivityRecord[] outRecord = new ActivityRecord[1];

int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,

aInfo, rInfo, voiceSession, voiceInteractor,

resultTo, resultWho, requestCode, callingPid,

callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,

options, ignoreTargetSecurity, componentSpecified, outRecord, container,

inTask);

Binder.restoreCallingIdentity(origId);

if (stack.mConfigWillChange) {

mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,

"updateConfiguration()");

stack.mConfigWillChange = false;

mService.updateConfigurationLocked(config, null, false);

}

if (outResult != null) {

outResult.result = res;

if (res == ActivityManager.START_SUCCESS) {

mSupervisor.mWaitingActivityLaunched.add(outResult);

do {

try {

mService.wait();

} catch (InterruptedException e) {

}

} while (outResult.result != START_TASK_TO_FRONT

&& !outResult.timeout && outResult.who == null);

if (outResult.result == START_TASK_TO_FRONT) {

res = START_TASK_TO_FRONT;

}

if (res == START_TASK_TO_FRONT) {

ActivityRecord r = stack.topRunningActivityLocked();

if (r.nowVisible && r.state == RESUMED) {

outResult.timeout = false;

outResult.who = new ComponentName(r.info.packageName, r.info.name);

outResult.totalTime = 0;

outResult.thisTime = 0;

} else {

outResult.thisTime = SystemClock.uptimeMillis();

mSupervisor.mWaitingActivityVisible.add(outResult);

do {

try {

mService.wait();

} catch (InterruptedException e) {

}

} while (!outResult.timeout && outResult.who == null);

}

}

}

final ActivityRecord launchedActivity = mReusedActivity != null

? mReusedActivity : outRecord[0];

mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);

return res;

}

}

一步步分析,

1、fd安全检查

if (intent != null && intent.hasFileDescriptors()) {

throw new IllegalArgumentException("File descriptors passed in Intent");

}

这里面检查intent是否有文件描述符,有的话抛异常。

2、获取信息

ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

后面一串主要是获取 ResolveInfo和ActivityInfo。

3、堆栈的config改变

stack = mSupervisor.mFocusedStack;

if (stack.mConfigWillChange) {

...

mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,

"updateConfiguration()");

stack.mConfigWillChange = false;

...

mService.updateConfigurationLocked(config, null, false);

}

4、startActivityLocked

这个是主要的启动函数,后面文章会分析。

5、关于outResult和等待

if (outResult != null) {

outResult.result = res;

if (res == ActivityManager.START_SUCCESS) {

mSupervisor.mWaitingActivityLaunched.add(outResult);

do {

try {

mService.wait();

} catch (InterruptedException e) {

}

} while (outResult.result != START_TASK_TO_FRONT

&& !outResult.timeout && outResult.who == null);

if (outResult.result == START_TASK_TO_FRONT) {

res = START_TASK_TO_FRONT;

}

}

if (res == START_TASK_TO_FRONT) {

ActivityRecord r = stack.topRunningActivityLocked();

if (r.nowVisible && r.state == RESUMED) {

outResult.timeout = false;

outResult.who = new ComponentName(r.info.packageName, r.info.name);

outResult.totalTime = 0;

outResult.thisTime = 0;

} else {

outResult.thisTime = SystemClock.uptimeMillis();

mSupervisor.mWaitingActivityVisible.add(outResult);

do {

try {

mService.wait();

} catch (InterruptedException e) {

}

} while (!outResult.timeout && outResult.who == null);

}

}

}

如果设置了outResult,分两步:

1、res == ActivityManager.START_SUCCESS 启动Activity成功了,等待mSupervisor.mWaitingActivityLaunched.add(outResult);

等待启动的时间,mWaitingActivityLaunched加入进去了。

后面文章我们会看到,Activity启动后,会过来设置这个值,并notifyall,去除这个等待。

2、res = START_TASK_TO_FRONT;

如果进一步结果告诉我,这个activity在前台了,等待mSupervisor.mWaitingActivityVisible.add(outResult);,

也就是等待Activity绘制完成显示的时候,这里mWaitingActivityVisible加入进去。

后面文章我们会看到,当Activity绘制完成后WMS会返回来告诉我们,并notifyall,去除这个等待。

整个startActivityMayWait分析完成了,我们将进入startActivityLocked。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值