1、从桌面应用的LauncherActivity点击开始:
//LauncherActivity继承子ListActivity,其实就是用于存放很多个应用的桌面 @Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); //执行到Activity的startActivity } //接着看Activity的startActivity ---又执行到了startActivityForResult public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { //mParent 是用于判断是否有父Activity,嵌套Activity中的,基本不会有,else就不看了 options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( //mMainThread就是ActivityThread的实例,应用程序入口main方法所在类。 //这个时候应用都还没启动哪里来的实例?其实这里是Launcher的,也就是当前的。 this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } //.... } else { //.... } }上面的代码Activity.
startActivityForResult方法通过mInstrumentation对象调用execStartActivity,Instrumentation主要用来监控应用程序和系统的交互。mMainThread其实是一个ActivityThread对象,实际上就是Launcher这个应用的ActivityThread,在Launcher启动时初始化。
//Instrumentation.java类 public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { //.... try { //.... int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), who.getAttributionTag(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; } //ActivityTaskManager.getService() 看看获取的是什么: /** ActivityTaskManager.java*/ public static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get(); } private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton = new Singleton<IActivityTaskManager>() { @Override protected IActivityTaskManager create() { //通过ServiceManager 获取一个服务,这里先不管什么服务,ServiceManager是管理系统中所有服务的类 final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); //获取一个什么样的服务呢?这里看到XXX.Stub.asInterface(),这不是经常见到AIDL的东西么?那看看谁实现了IActivityTaskManager.Stub接口 return IActivityTaskManager.Stub.asInterface(b); } }; //找到了 就是它: public class ActivityTaskManagerService extends IActivityTaskManager.Stub ActivityTaskManagerService简称ATMS, 到这里明白:Launcher启动一个APP通过一系列的操作,
使用AIDL的方式通过Binder
将数据交给了ATMS,(这里是启动应用的一次IPC通信,即Launcher和ATMS的一次通信)ATMS开始处理消息,Instrumentation已经将Launcher所在的进程(whoThread参数,就是前面到mMainThread.getApplicationThread)传过来了,AMS将其保存为一个ActivityRecord对象,这个对象中有一个ApplicationThreadProxy即Binder的代理对象,AMS通ApplicationTreadProxy发送消息给Launcher。ATMS在接收到消息后,会通知前一个页面该休息了,也就是进入pause状态,这里通知Launcher你该休息了:
//ActivityStack.java private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { //... ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */); //... boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false); if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, next, false); } //... if (next.attachedToProcess()) { //应用已经启动 try { //... transaction.setLifecycleStateRequest( ResumeActivityItem.obtain(next.app.getReportedProcState(), getDisplay().mDisplayContent.isNextTransitionForward())); mService.getLifecycleManager().scheduleTransaction(transaction); //... } catch (Exception e) { //... mStackSupervisor.startSpecificActivityLocked(next, true, false); return true; } //... // From this point on, if something goes wrong there is no way // to recover the activity. try { next.completeResumeLocked(); } catch (Exception e) { // If any exception gets thrown, toss away this // activity and try the next one. Slog.w(TAG, "Exception thrown during resume of " + next, e); requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, "resume-exception", true); return true; } } else { //冷启动流程 mStackSupervisor.startSpecificActivity(next, true, true); } }首先startPausingLocked()让上一个页面进入pause状态, 然后开始判断要启动的APP的进程是否存在
,如果存在就直接启动目标Activity,如果不存在就创建进程。如果当前是Launcher的话,存在进程,进入到 热启动流程 ,不存在,进入到
冷启动流程
。也是Activity生命周期中为啥启动一个Activity时,先执行了onPause后,目标Activity才开始执行生命周期方法。接着看冷启动流程:
//ActivityStackSupervisor.java void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid); boolean knownToBeDead = false; if (wpc != null && wpc.hasThread()) { try { //继续判断是否存在进程,如果存在就返回了 realStartActivityLocked(r, wpc, andResume, checkConfig); return; } catch (RemoteException e) { } knownToBeDead = true; } //.... mService是ATMS的实例对象,这里去创建了进程了,去看看怎么创建进程的 mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity"); }ATMS如何创建新的进程?或者说怎么与Zygote进行通信,让Zygote进程fork()进程的,来看ATMS中:
//ActivityTaskManagerService.java void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, String hostingType) { try { //... // Post message to start process to avoid possible deadlock of calling into AMS with the //这里的意思:发布消息以启动进程,以避免调用AMS时可能出现的死锁 // ATMS lock held. final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead, isTop, hostingType, activity.intent.getComponent()); mH.sendMessage(m); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } }ActivityManagerInternal::startProcess看这了,启动一个新的进程:
//是一个抽象方法,找到实现它的地方:public abstract void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);//实现ActivityManagerInternal::startProcess方法的类在ActivityManagerService中://ActivityManagerService.javapublic class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { // ... ... public final class LocalService extends ActivityManagerInternal { @Override public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, String hostingType, ComponentName hostingName) { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:" + processName); } //线程同步,防止多线程创建进程,进程创建只能支持单线程,所以后续AMS与Zygote的通信不能用Binder通信,选择使用Socket synchronized (ActivityManagerService.this) { startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */, new HostingRecord(hostingType, hostingName), false /* allowWhileBooting */, false /* isolated */, true /* keepIfLarge */); } } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } // ... ...}这里可以看到冷启动流程中,把创建新进程的任务交给了AMS去做,最后执行到ZygoteProcess中,Zygote进程负责创建新的进程。
//ZygoteProcess.java private Process.ProcessStartResult attemptUsapSendArgsAndGetResult( ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx, IOException { try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) { final BufferedWriter usapWriter = new BufferedWriter( new OutputStreamWriter(usapSessionSocket.getOutputStream()), Zygote.SOCKET_BUFFER_SIZE); final DataInputStream usapReader = new DataInputStream(usapSessionSocket.getInputStream()); usapWriter.write(msgStr); usapWriter.flush(); Process.ProcessStartResult result = new Process.ProcessStartResult(); result.pid = usapReader.readInt(); // USAPs can't be used to spawn processes that need wrappers. result.usingWrapper = false; if (result.pid >= 0) { return result; } else { throw new ZygoteStartFailedEx("USAP specialization failed"); } } }可以看到,这里其实是通过socket和Zygote进行通信,BufferedWriter用于读取和接收消息。这里将要新建进程的消息传递给Zygote,由Zygote进行fork进程,并返回新进程的pid。这过程中也实例化ActivityThread对象,然后执行main方法:
//RuntimeInit.java protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try { cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { throw new RuntimeException( "Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException( "Problem getting static main on " + className, ex); } //... return new MethodAndArgsCaller(m, argv); }这里通过反射的方式调用了main方法,之后就进入到APP的主入口main方法了。
public static void main(String[] args) { //... Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); //这里将会告诉AMS,进程创建完毕,我启动好了...同时创建Application thread.attach(false, startSeq); //... if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } //... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }到这里,AMS告诉Zygote创建新的进程已经就完事了, 事后一根烟,赛过活神仙 ,我先休息一下....
现在继续:
创建进程完毕其实应用就已经启动了,因为一个应用其实就是一个进程,这个时候这个应用就开始自己去创建Application、启动Activity了,然后重新开始startActivity,进入到最开始的地方,这个时候判断的目标Activity所在的进程已经存在,则进入到Activity的启动流程,最终执行到ActivityThread的handleLaunchActivity()方法:
//ActivityThread.javapublic Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { //... WindowManagerGlobal.initialize(); //... 接着执行performLaunchActivity final Activity a = performLaunchActivity(r, customIntent); //... return a; }private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //创建ContextImpl ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //创建Activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); } try { if (activity != null) { //完成activity的一些重要数据的初始化 activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback, r.assistToken); if (customIntent != null) { activity.mIntent = customIntent; } //设置activity的主题 int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme(theme); } //调用activity的onCreate方法,到这里,就几乎结束了... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } } } return activity; }然后到这里,第二场也结束了,总结一下这次的成果,消耗了不知道多少精力,精疲力尽的感觉,只为了最后那一刻,那就是: 注意了,这里划重点,会考!
**1、Launcher被调用点击事件,转到Instrumentation类的startActivity方法。
2、Instrumentation通过AIDL方式使用Binder机制告诉ATMS要启动应用的需求。
3、ATMS收到需求后,反馈Launcher,让Launcher进入Paused状态
4、Launcher进入Paused状态,ATMS将创建进程的任务交给AMS,AMS通过socket与Zygote通信,告知Zygote需要新建进程。
5、Zygote fork进程,并调用ActivityThread的main方法,也就是app的入口。
6、ActivityThread的main方法新建了ActivityThread实例,并新建了Looper实例,开始loop循环。
同时ActivityThread也告知AMS,进程创建完毕,开始创建Application,Provider,并调用Applicaiton的attach,onCreate方法。
7、最后就是创建上下文,通过类加载器加载Activity,调用Activity的onCreate方法。**
最后:其实了解启动流程,最终也是为了启动优化做准备吧,这么看来,启动优化可以做的就是最后的:
1、Application的attach方法,MultiDexApplication会在方法里面会去执行MultiDex逻辑。所以这里可以进行MultiDex优化,比如今日头条方案就是单独启动一个进程的activity去加载MultiDex。
2、Application的onCreate方法,大量三方库的初始化都在这里进行,所以我们可以开启线程池,懒加载等等。把每个启动任务进行区分,哪些可以子线程运行,哪些有先后顺序。
3、Activity的onCreate方法,同样进行线程处理,懒加载。或者预创建Activity,提前类加载等等。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。