第1章 Phone
phone进程指的是“com.android.phone”,代码位于packages/services/Telephony。Phone进程是开机启动进程的,它的AndroidManifest.xml文件中的以下代码决定了其将在DBM下就会启动了,且异常退出后会自动重启。
图1
persistent表示应用是常驻的;directBootAware表示应用是可直接启动的。这两个字段决定了PhoneApp开机后,将被ActivityManagerService启动。
拥有android:persistent=true属性的app将不能被kill或kill后会自动重启。由此可见Phone应用是系统常驻进程,一旦起来后就会一直运行,不会被杀死(除非Phone自己发生了运行时错误而崩溃)。
常驻进程ActivityManagerService(简称AMS)会在初始化完成后,主动启动persistent=true的进程。在SystemServer初始化系统核心服务后,调用AMS的systemReady(Runnabler)。
android:directBootAware=”true”:设备开机后在用户解锁前会进入到一个DirectBootMode,这是系统会发送ACTION_LOCKED_BOOT_COMPLETED广播,等用户解锁之后,系统才会发送ACTION_BOOT_COMPLETED广播。
从 Android N 开始,在首次开机时,在用户尚未来得及解锁设备之前,设备可直接启动到一种名为 Direct Boot(直接启动)的新模式中。在此模式下,操作系统可以全功能运行,但不允许访问私有应用数据,只能运行经过更新、可支持直接启动功能的应用。
当SystemServer进程被zygote进程创建后,在SystemServer的run方法中会启动系统所需的关键服务
图2启动关键服务
在startBootstrapService()中,会启动ActivityManagerService。
图3启动ActivityManagerService
在startOtherService()中,调用ActivityManagerService.systemReady()方法。
图4调用ActivityManagerService.systemReady()
1)ActivityManagerService类的systemReady(),在这里phoneapp被创建。
//注意此处的参数MATCH_DIRECT_BOOT_AWARE
图5 phoneApp被创建
启动所有PackageManager.MATCH_DIRECT_BOOT_AWARE为true的进程。systemReady将调用startPersistentApps启动某一类Application。
2)startPersistentApps 方法中addAppLocked()加载应用。
AppGlobals.getPackageManager().getPersistentApplications(…).getList();
//从PackageManagerService中获取同时具有Persistent和directBootAware标签的应用列表。
图6调用addAppLocked()启动这些应用
3)addAppLocked()中:if(app==null)没有进程记录,创建一个进程记录。startProcessLocked()//准备创建进程。
图7调用startProcessLocked()
4)startProcessLocked():
startResult = Process.start(……)//利用socket发送消息给zygote分裂出应用所需的进程;
//进程创建出后,将调用对应类的main函数,对于PhoneApp而言,即android.app.ActivityThread。
图8 Process.start()
Process.start()创建一个新进程,Telephony的服务及RIL相关代码都运行在此进程中。
图9 return zygoteProcess.start()发送消息到zygote服务进程的socket端口,请求创建新的进程
图10发送消息到zygote服务进程的socket端口
ZygoteProcess类的start方法,return startViaZygote(……)发送消息到zygote服务进程的socket端口,请求创建新的进程。
图11 return startViaZygote(……)
startViaZygote(……)
图12 zygoteSendArgsAndGetResult发送消息到zygote的socket端口,请求创建新的进程
ZygoteConnection.java
zygote进程接收到AMS的请求后,由ZygoteConnection负责处理请求:
// 从socket中读取参数
……
//Zygote调用本地方法创建进程
图13至此phone进程已经创建完成了,但实际上PhoneApp的代码还没有加载。
调用ZygoteInit.zygoteInit来加载phoneApp的代码。
图14 RuntimeInit.applicationInit()初始化应用代码
调用findStaticMain()。
图15调用findStaticMain()
在findStaticMain()中会return new MethodAndArgsCaller(),MethodAndArgsCaller()主要是清除父进程中的一些调用堆栈,这样子进程就从ActivityThread.main开始了自己的堆栈调用。
图16 new 一个MethodAndArgsCaller()
MethodAndArgsCaller()方法,主要是清除父进程中的一些调用堆栈,这样子进程就从ActivityThread.main开始了自己的堆栈调用。
图17 MethodAndArgsCaller()方法
1) 在ActivityThread.java文件的main()方法中,有Looper。
Looper.prepareMainLooper();启动主线程。这样Phone的创建就算是完成了。thread.attach(false); //PhoneApp不是系统App。
图18
2) 看一下attach()
RuntimeInit.setApplicationObject(mAppThread.asBinder()); //binder通信,获取Remote端;
final IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread); //将ApplicationThread传给AM,实际上传递的是binder代理;
图19 调用ActivityManagerService.attachApplication()
从上面的代码可以看出,流程再次回到了ActivityManagerService。
1)attachApplication()调用attachApplication()
图20
2)attachApplication(),将调用ApplicationThread的bindApplication。
图21调用bindApplication()
1)ActivityThread.java的bindApplication(),会sendMessage()给自己,在该类的handleMessage中进行消息处理。(在PhoneApp中的binder解析完收到的数据后,触发BIND_APPLICATION消息给H)
图22 sendMessage()
2)handleMessage处理BIND_APPLICATION。
图23 handleMessage处理BIND_APPLICATION,调用handleBindApplication()
3)handleBindApplication()执行 mInstrumentation.callApplicationOnCreate(app);
图24 Instrumentation.java的callApplicationOnCreate()
图24启动app
经过上面的过程,PhoneApp终于可以启动了。
1. SystemServer进程会创建出AM和PM,PM会加载Application的信息。 (AM:ActivityManagerService;PM:PackageManager)
2. 当AM的SystemReady被调用后,将利用PM得到具有persistent和directBootAware的应用列表,PhoneApp就在其中。
3. AM利用socket向zygote发送消息,启动PhoneApp对应的进程。
4. zygote进程启动PhoneApp进程后,将利用反射调用PhoneApp中ActivityThread的main函数。
5. ActivityThread的main函数被调用后,将利用binder通信向AM发送消息;AM进行对应的处理,处理完成后,同样利用binder通信将处理结果返回给ActivityThread。
6. 最后ActivityThread收到处理结果后,完成最后的准备工作(设置参数之类),并调用PhoneApp的onCreate函数。
phoneApp启动之后:在PhoneApp中new PhoneGlobals,执行PhoneGlobals.onCreate()方法;
在PhoneGlobals中执行PhoneFactory.makeDefaultPhones()方法;
在PhoneFactory的makeDefaultPhones()方法中,实例化了TelephonyDevController、UiccController、SubscriptionController、SubscriptionInfoUpdater、SmsApplication、PhoneSwitcher等。