前言:
电话管理是Android 系统支持的重要的业务之一,提供接听电话,收发短信、电话薄、网络事件监听、
读取用户信息、2G/3G/4G信号切换等功能。由上到下分为4层, PHONE应用层,Telephony框架实现层,
RIL层。本文基于android 5.1,架构图如下,
整个框架的调用流程图如下,
整个网络虽然涉及到的进程也比较多,但是仔细分析起来关键点没有多少。本文的关键点在于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方法,方法的调用流程图如下,
初始化主要步骤如下,
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的初始化等等。