好记性不如烂笔杆。所以还是有必要给这些都记下来,隔段时间再看的时候也不至于一片茫然。
顺带提一下目前自己阅读源码的三种途径:1.在线阅读,类似的网站有androidxref等;2.使用工具如Source Insight 4.0导入源码进行阅读;3.使用as加载修改过的android.jar包来进行阅读。这三种更喜欢as的方式,函数的跳转和变量的颜色区分的最好,Source Insight可能用的不熟练,总感觉比as差点事,但是Source Insight好处就是占用内存资源少,而网站更适合查找部分代码,比如各个版本代码的不同部分。
好了,开始正题。startActivity在最近的几个安卓版本中部分代码做了改动,虽然整体还是一样的架构,比如;7.0之前是binder来实现进程间通信的,8.0之后改为aidl去实现了,虽然本质上实现还是binder,aidl只是又做了一层封装;又比如9.0在启动activity上与之前的启动方式相比,由函数直接调用改为类似事物的方式去启动了。但是,整体的架构还是一样的,ams仍然是那个最重要的中间者,而启动的最后仍然会回到activityThread中去处理。
在activity中调用startActivity,首先会调用Activity类中的startActivity方法,以前的老版本这一步是调用context的startActivity方法;
此方法会调用
此处传入startActivity方法的第二个参数为null,因此我们直接跟进else里面的方法startActivityForResult(intent, -1);
在此方法中我们又看到了熟悉的类Instrumentation,在Instrumentation类中调用了execStartActivity,需要注意的是这是个重载方法,我们只找我们参数对应的方法即可,下面是这个方法的关键代码
此处开始进程切换。ActivityManager.getService().startActivity这段代码其实是跨进程调用了ActivityManagerService里面的方法startActivity,关于ActivityManagerService这个服务(以下简称AMS)的作用此处不做讲解。下面来看下ActivityManager.getService()这个方法的具体实现
可以看到getService方式内部调用了IActivityManagerSingleton.get(),IActivityManagerSingleton其实是一个泛型单例类,核心实现是重写的create方法,此方法内部通过调用ServiceManager.getService(Context.ACTIVITY_SERVICE)得到一个java层的binder,ServiceManager是系统Service服务的管家,内部维护了一个map来存储各个Service对象,ACTIVITY_SERVICE就是AMS在map的key值。IActivityManager.Stub.asInterface(b)这行代码就属于aidl的范畴了,asInterface方法据说内部调用了native方法通过binder驱动,然后经过映射找到另一个进程的binder,然后层层返回,最后到java层,这样我们就拿到了可以和另一个进程进行通信的钥匙。
8.0之前这一部分没有使用aidl,而是直接使用binder实现的,具体的代码在ActivityManagerNative这个类里面。替换为binder之后代码更为精简了,便于阅读,对于初学者也更为友好,不用在ActivityManagerNative和代理类之间绕来绕去的,而机器生成的代码比人写的代码也更为安全。
接下来继续startActivity的流程,代码在系统进程AMS的startActivity处开始
此处留意第一个参数IApplicationThread caller,后续有用
第二个startActivityAsUser方法也是和之前不一样的地方,obtainStarter方法通过工厂模式生成了一个ActivityStarter对象。真正的代码跑到了ActivityStarter的execute方法里面:
这样启动activity的主要流程就跑到ActivityStarter类里面了,接下来看startActivity方法
此方法里面又调用了一个startActivity方法,而这个startActivity方法代码就比较多了,主要对activity启动的权限和调用者等做了校验,不关注这个直接走到方法底部还是一个startActivity方法,下面贴上这个startActivity方法的代码
startActivityUnchecked方法,此方法也比较长,主要对activity的启动模式和activity栈做了处理,onNewIntent就是在这触发的
接下来又跳转到了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
ActivityStack类的resumeTopActivityUncheckedLocked方法,这个方法也比较长,只关注最后面的startSpecificActivityLocked方法
ActivityStackSupervisor类startSpecificActivityLocked方法:
startSpecificActivityLocked方法里面对是应用内打开activity还是从桌面打开activity做了判断,如果从桌面打开activity,此时应用还没有主进程,就会调用mService.startProcessLocked方法创建新的进程,然后再走startActivity的流程。此处我们关注realStartActivityLocked方法,带上real就证明离真相很近了。
此处是9.0与8.0最大的区别,改用事物的方式去启动activity了,接下来看事物的提交scheduleTransaction方法
调用的是ClientTransaction类的schedule方法,接下来看schedule方法
调用了mClient对象的方法,mClient是一个继承了IApplicationThread接口的实现类,是不是很眼熟,和前面的caller类型一样,而IApplicationThread的实现类是ApplicationThread,ActivityThread的内部类
好的,又调用了ActivityThread类的scheduleTransaction方法,搜索了一下ActivityThread类里面并没有这个方法,这个时候不要慌,看下ActivityThread的父类ClientTransactionHandler,发现原来这个方法在父类里面实现了
又给ActivityThread发送了一个消息,接下来看处理这个消息的代码
这个事务在这又被mTransactionExecutor的方法execute给执行了。。。
接下来看TransactionExecutor类的execute方法
在这个方法里面主要执行了两个方法,根据名字判断executeLifecycleState可能只是改变状态而executeCallbacks方法可能更有料,接下来看executeCallbacks方法的代码
然后继续跟item.execute这行代码,可以看到item是ClientTransactionItem类的对象,那么这个对象在哪被复制的,回到事务最初创建的地方,ActivityStackSupervisor类的realStartActivityLocked方法
可以看到此处的clientTransaction调用了addCallback方法,而刚才的executeCallbacks方法中出现了clientTransaction.getCallbacks方法,因此这个LaunchActivityItem就是item,接下来看LaunchActivityItem类中的execute方法
可以看到client.handleLaunchActivity这段代码就是之前8.0中的代码,兜兜转转这么久,终于回到了这里,而这个client就是前面继承了ClientTransactionHandler的ActivityThread类,接下来看handleLaunchActivity代码的实现
其中的关键方法performLaunchActivity,其中完成了activity实例的创建,Application的实例化,window的依附等操作,activity的生命周期也开始启动,至此activity的创建就算告一段落了。