Activity启动流程
Activity.startActivity—> startActivityForUser –>Instrumentation.excuStartActivity–>ATM —startActivity ->判断 需要启动的 Activity 所在的进程 是否已经启动 ->如果启动了 realStartActivityLocked 进程不存在:mService.startProcessAsync -> AMS 如何通知到 zygote —>zygote 如何创建 应用进程的 ===system server 创建一样流程一样的
点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
system_server进程接收到请求后,向zygote进程发送创建进程的请求;
Zygote进程fork出新的子进程,即App进程;
App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面
init.cpp#main() -> LoadBootScripts(actionManager, serviceList) -> 解析init.rc -> trigger zygote-start
Launcher进程请求AMS 根Activity的启动流程就是桌面上点击一个应用图标进入到应用的第一个Activity的流程,桌面可以看成一个程序,即Launcher。
当系统开机后,Launcher也随之被启动,然后将已经安装的应用程序图标显示到桌面上,当点击一个应用图标其实就是相当于点击活动中的一个button,其相应事件就是Launcher进程请求AMS来启动该应用程序。
请求的入口就是Launcher的startActivitySafe方法:packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public boolean startActivitySafely (View v, Intent intent, ItemInfo item) { ... intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { ... if (isShortcut) { startShortcutIntentSafely(intent, optsBundle, item); } else if (user == null || user.equals(Process.myUserHandle())) { startActivity(intent, optsBundle); } else { LauncherAppsCompat.getInstance(this ).startActivityForProfile( intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } ... return true ; } catch (ActivityNotFoundException|SecurityException e) { ... } return false ; }
该方法为根Activity设置了flag,即根Activity会在新的任务栈中启动。
frameworks/base/core/java/android/app/Activity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Override public void startActivity (Intent intent, @Nullable Bundle options) { if (options != null ) { startActivityForResult(intent, -1 , options); } else { startActivityForResult(intent, -1 ); } } public void startActivityForResult (@RequiresPermission Intent intent, int requestCode) { startActivityForResult(intent, requestCode, null ); } public void startActivityForResult ( @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options ) { if (mParent == null ) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this , mMainThread.getApplicationThread(), mToken, this , intent, requestCode, options); ... } ... }
每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options ) { ... try { ... int result = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null , requestCode, 0 , null , options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException ("Failure from system" , e); } return null ; } @UnsupportedAppUsage public static IActivityManager getService () { return IActivityManagerSingleton.get(); } @UnsupportedAppUsage private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton <IActivityManager>() { @Override protected IActivityManager create () { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
在Singleton中的create方法中由于b是AMS引用作为服务端处于SystemServer进程中,与当前Launcher进程作为客户端与服务端不在同一个进程,所以am返回的是IActivityManager.Stub的代理对象,此时如果要实现客户端与服务端进程间的通信,只需要在AMS继承了IActivityManager.Stub类并实现了相应的方法,这样Launcher进程作为客户端就拥有了服务端AMS的代理对象,然后就可以调用AMS的方法来实现具体功能了,就这样Launcher的工作就交给AMS实现
AMS发送创建应用进程请求
AMS将请求任务转移给Process 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @Override public final int startActivity ( IApplicationThread caller, String callingPackage, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(...); } public final int startActivityAsUser (IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivity" ); userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser" ); return mActivityStartController.obtainStarter(...) .setMayWait(userId) .execute(); } ActivityStarter obtainStarter (Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); }
startActivity方法经过多个方法调用会去执行startActivityAsUser方法,在startActivityAsUser方法最后会返回mActivityStartController的一长串链式调用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 int execute () { try { if (mRequest.mayWait) { return startActivityMayWait(...); } else { return startActivity(...); } } finally { onExecutionComplete(); } } private int startActivityMayWait (...) { ..... ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); int res = startActivity(...); .... } private int startActivity (...) { ... result = startActivityUnchecked(...); ... postStartActivityProcessing(r, result, mTargetStack); return result; } private int startActivityUnchecked (...) { ... if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 ) { newTask = true ; result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack); } else if (mSourceRecord != null ) { result = setTaskFromSourceRecord(); } else if (mInTask != null ) { result = setTaskFromInTask(); } else { setTaskToCurrentTopOrCreateNewTask(); } ... if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { ... } else { if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked" ); } mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else { mTargetStack.addRecentActivityLocked(mStartActivity); } ... }
在startActivityAsUser的链式方法中我们调用了setMayWait这个方法,所以这里的mRequest.mayWait为true,故会继续调用startActivityMayWait方法。
startActivityMayWait方法经过调用多次的startActivity方法后会调用到startActivityUnchecked这个方法,会根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它。
无论以何种模式启动最终都会调用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void startSpecificActivityLocked ( ActivityRecord r, boolean andResume, boolean checkConfig ) { ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true ); if (app != null && app.thread != null ) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android" .equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return ; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } } mService.startProcessLocked(r.processName, r.info.applicationInfo, true , 0 ,"activity" , r.intent.getComponent(), false , false , true ); }
在方法中首先获取到了即将要启动的Activity所在的应用进程,假如是普通的Activity的启动流程的活,这个进程肯定是存在的,所以将执行realStartActivityLocked的方法。但是我们现在讨论的是根Activity的启动流程,由于应用都还未启动,意味着根Activity所在的应用进程还未创建,而mService其实就是AMS,所以这里将调用AMS的startProcessLocked。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 private final boolean startProcessLocked (ProcessRecord app, String hostingType, String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) { ... int uid = app.uid; int [] gids = null ; int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; if (!app.isolated) { ... if (ArrayUtils.isEmpty(permGids)) { gids = new int [3 ]; } else { gids = new int [permGids.length + 3 ]; System.arraycopy(permGids, 0 , gids, 3 , permGids.length); } gids[0 ] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); gids[1 ] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); gids[2 ] = UserHandle.getUserGid(UserHandle.getUserId(uid)); if (gids[0 ] == UserHandle.ERR_GID) gids[0 ] = gids[2 ]; if (gids[1 ] == UserHandle.ERR_GID) gids[1 ] = gids[2 ]; } ... final String entryPoint = "android.app.ActivityThread" ; return startProcessLocked(...); } private boolean startProcessLocked (...) { .... final ProcessStartResult startResult = startProcess(...); ... } private ProcessStartResult startProcess (...) { .... if (hostingType.equals("webview_service" )) { startResult = startWebView(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null , new String [] {PROC_START_SEQ_IDENT + app.startSeq}); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, new String [] {PROC_START_SEQ_IDENT + app.startSeq}); checkTime(startTime, "startProcess: returned from zygote!" ); return startResult; } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } }
在startProcess方法里将调用Process.start来发送应用创建进程的请求。这样AMS就将发送请求的事交给了Process
Process向Zygote进程发送创建应用进程请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public static final ProcessStartResult start (...) { return ZYGOTE_PROCESS.start(...); } public final Process.ProcessStartResult start (...) { try { return startViaZygote(...); } catch (ZygoteStartFailedEx ex) { } } private Process.ProcessStartResult startViaZygote (...) throws ZygoteStartFailedEx { ArrayList<String> argsForZygote = new ArrayList <String>(); argsForZygote.add("--runtime-args" ); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); argsForZygote.add("--runtime-flags=" + runtimeFlags); if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) { argsForZygote.add("--mount-external-default" ); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) { argsForZygote.add("--mount-external-read" ); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) { argsForZygote.add("--mount-external-write" ); } argsForZygote.add("--target-sdk-version=" + targetSdkVersion); ... synchronized (mLock) { return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), useBlastulaPool, argsForZygote); } }
在startViaZygote中会创建字符串列表argsForZygote来保存将要创建的应用进程的启动参数,然后最后会调用zygoteSendArgsAndGetResult方法,而在这个方法中第一个参数会调用openZygoteSocketIfNeeded方法,第三个参数就是启动参数列表。
拓扑排序 视频讲解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 public static startupSortStore sort (List<? extends startup<?>>startupList) { Map<Class<? extends startup >, Integer>inDegreeMap= new HashMap <>(); Deque<Class<? extends Startup >>zeroDeque = new ArrayDeque <>(); Map<Class<? extends Startup >,Startup<?>> startupMap = new HashMap <>(); Map<Class<? extends startup >, List<Class<? extends Startup >>> startupchildrenMap = new HashMap <>(); for (startup<?>startup :startupList){ startupMap.put(startup.getClass(),startup); int dependenciesCount=startup.getDependenciesCount(); inDegreeMap.put(startup.getclass(),dependenciescount); if (dependenciesCount==0 ) { zeroDeque.offer(startup.getclass()); } else { for (Class<? extends startup <?>>parent : startup.dependencies()){ List<Class<? extends startup >>children = startupchildrenMap.get(parent); if (children == null ){ children = new ArrayList <>(); startupchildrenMap.put(parent,children); } children.add(startup.getclass()); } } } List<Startup<?>>result = new ArrayList <>(); while (!zeroDeque.isEmpty()) { Class<?extends startup >cls =zeroDeque.poll(); Startup<?>startup =startupMap.get(cls);result.add(startup); if (startupChildrenMap.containsKey(cls)){ List<Class<? extends startup >>childstartup = startupchildrenMap.get(cls); for (Class<?extends startup >childcls :childstartup){ Integer num=inDegreeMap.get(childcls); inDegreeMap.put(childcls,num-1 ); if (num-1 ==0 ){ zeroDeque.offer(childcls); } } } } return new StartupSortStore (result, startupMap, startupchildrenMap); }