前言:

电话管理是Android 系统支持的重要的业务之一,提供接听电话,收发短信、电话薄、网络事件监听、

读取用户信息、2G/3G/4G信号切换等功能。由上到下分为4层, PHONE应用层,Telephony框架实现层,

RIL层。本文基于android 5.1,架构图如下,

整个框架的调用流程图如下,

android app 进程id 进程com.android.phone_android app 进程id

整个网络虽然涉及到的进程也比较多,但是仔细分析起来关键点没有多少。本文的关键点在于Framework的几个进程,

上层的应用以及第三方有关phone的应用都是通过TelephonyManager这个API接口和phone进程进行binder通信,

当然手机中有部分操作本身就运行于phone进程中。

Phone进程一方面通过RIL.java文件利用socket和hardware中的rild守护进程进行通信;另外一方面通过

NetworkAgent利用AsyncChannel和systemerver进程的ConnectivityService服务进行通信,管理网络连接等等。

与此同时, systemerver进程还通过socket机制和netd守护进程完成网络的相关操作等等。

在整个android系统中,phone模块需要处理很多事务,例如电话的接听/来去电,短信的收发等等,但是本文主要论述

Framework层的Phone服务进程有关2G/3G/4G信号切换流程。

1, Phone服务进程

Phone服务进程 (包名com.android.phone,以下简称phone进程)主要代码位于以下目录中,

packages/services/Telephony/

frameworks/opt/telephony/

frameworks/base/telephony/

1.1 phone进程启动

Phone进程并不是在点击Luncher上的图标启动的,而是在系统开机启动时,又ActivityManagerService启动的。

Phone的AndroidManifest.xml文件配置了如下属性:

<application android:name="PhoneApp"  
android:persistent="true"  
android:label="@string/dialerIconLabel"  
android:icon="@drawable/ic_launcher_phone">

对于android:persistent="true" 的应用是在Android开机时启动的, 在android启动完成时通过调用systemReady

方法来完成并通知服务启动。ActivityManagerService服务的systemReady有关启动android:persistent="true" 

应用的代码如下,

//通过PackageManager查询到所有android:persistent属性为true的应用
List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);
if (apps != null) {
    int N = apps.size();
int i;
//遍历所有应用,并启动
for (i=0; i<N; i++) {
    //得到每个应用的相关信息
       ApplicationInfo info= (ApplicationInfo)apps.get(i);
       if (info != null &&!info.packageName.equals("android")) {
             //启动应用
            addAppLocked(info, false, null /* ABI override */);

首先查询apk文件中android:persistent="true"的应用;

然后调用addAppLocked方法(最后调用startProcessLocked方法)启动应用。

1.2 初始化

PhoneApp继承自Application,因此,phone进程的入口方法为PhoneApp的onCreate方法,方法的调用流程图如下,


android app 进程id 进程com.android.phone_初始化_02


初始化主要步骤如下,

1, RIL 初始化,

 开启发送消息的线程:

mSenderThread = new HandlerThread("RILSender" + mInstanceId);
mSenderThread.start();

利用mSenderThread 构建RILSender 对象,这样就可以向底层发送套接字消息了。

Looper looper = mSenderThread.getLooper();
mSender = new RILSender(looper);

同样, 构建一个RILReceiver对象,接收底层发送的套接字消息

mReceiver = new RILReceiver();
mReceiverThread = new Thread(mReceiver, "RILReceiver" + mInstanceId);
mReceiverThread.start();

2,状态/消息的注册,这样,底层传输上来的消息才可以分发处理。

例如,在GsmCallTracker的构造函数中注册电话状态,

mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);

3, PhoneProxy相关代理类的初始化、NotificationMgr的初始化等等。