看源码重要性不多说了,本文通过跟踪代码学习android根activity(由Laucher启动的activity)的启动过程。
1 源码的下载与编译(网上很多教程),在此说一下我的方法
- 我是windows下安装ubutun 16.04虚拟机(站硬盘80G),在ubuntu上下载和编译源码,生成android.iml和android.ipr文件,然后想打开as工程一样open这个android.ipr文件,然后配置JDK和SDK sdk的android版本和源码的版本保持一致,然后运行一个对应的nexus 虚拟机(如果有nexus手机直接连接就行了),然后在Launcher.java 的 startActivity(View v,Intent intent ,int flag)上打断点debug com.android.launcher进程,随便启动一个app程序就会跳刀断点停止,就可以跟踪代码了。
Launcher.startActivity
当点击一个app的图标,Launcher通过startActivity把view,intent,flag传递进来,通过debugger可以看到intent的一些信息
1组件的action、category
2组建信息对象 mComponent 通过mCompoent可以获取组件类名包名接着比较易懂调用Activity的startActivity,最终跳转到startActivityForResult
mToken 是一个Ibinder 它和applicationThread用于和ActivityManagerService 进程间通信
- 接着step into mInstrumentation.execStartActivity
重点在ActivityManagerNative.getDefault().startActivity
看一下getDefault方法
static public IActivityManager getDefault() {
return gDefault.get();
}
根据gDefault.get()返回一个IActivityManager
ActivityManager没有放到AMS类家族里那么想要用ActivityManager的方法就要用它的代理类ActivityManagerProxy
那么gDefault.get()就返回一个ActivityManagerProxy负责ActivityManager的工作。
那么gDefault如何获取这个代理的呢?
ServiceManager.getService(“activity”)得到ActivityManagerService的代理对象,
然后通过asInterface(ams)将 创建一个ActivityManagerProxy(IBinder),然后通过ActivityManagerProxy的内部AMS代理对象mRomote向AMS发送一个类型为TRANSACTION类型的进程间通信请求。
这样根Activity启动的第一步完成,下次说第二步。