- A+
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。
Android app启动流程:调用startProcessLocked的几种情况(1)
Android app启动流程:startProcessLocked函数分析(2)
Android app启动流程:Process.start(3)
Android app启动流程:startservice(4)
Android app启动流程:broadcast广播的注册(5)
Android app启动流程:广播的发送broadcastIntentLocked(6)
Android app启动流程:广播的发送scheduleBroadcastsLocked(7)
Android app启动流程:广播的发送processNextBroadcast(8)
Android app启动流程:关于FocusedStack的研究(9)
Android app启动流程:startActivityMayWait分析(10)
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏