Telephony之进程与实体

一、Telephony进程


        整个Framework层的Telephony框架运行在一个叫做Phone(com.android.phone)的进程中。而这个进程是在packages\services\Telephony模块中被创建的(Android4.4平台)。并且该模块在AndroidManifest.xml中有如下关键的声明:
  1. <application android:name="PhoneApp"  
  2.     android:persistent="true"  
  3.     android:label="@string/phoneAppLabel"  
  4.     android:icon="@mipmap/ic_launcher_phone"  
  5.     android:supportsRtl="true">  
        这个声明创建了一个名叫“PhoneApp”的application,并且确定了他的name、label、icon等信息,而且将该application的persistent属性置为true。那么这个persistent属性的作用是什么呢?
        这里的persistent属性具备两个关键作用:
        1、该模块会在开机时被系统自动初始化;
        2、该模块所在的进程(com.android.phone)由于任何原因被kill掉之后,都会自动重启;

        以上两点是十分必要的,他保证/导致了两个效果:
        1、所有Application层和Framework层中与Telephony相关的操作,包括各种Service的创建、与RIL层交互的RILJ的初始化等,都是通过Phone进程创建的;
        2、Phone进程由于任何原因被kill掉后,都会发生重新搜网的动作;


二、Telephony实体对象


        前面介绍了Telephony的框架和进程,那么当发生具体的某个通讯请求,比如打电话、发短信时,该如何操作呢?
        这里要引入一个非常重要的对象: Phone对象。该对象可以看做是Telephony框架的实体,可以向该对象发起各种通讯相关的请求,可以说,Phone对象是Telephony整个框架的核心,他负责与RIL层的交互。
        而这个Phone对象就是在PhoneApp这个application初始化过程中被创建的。我们就从入口开始,来查看Phone进程的创建过程:
        在PhoneApp的onCreate()方法中,会new出PhoneGlobals的对象,并接着调用该对象的onCreate方法:
  1. @PhoneApp.java  
  2. public void onCreate() {  
  3.     if (UserHandle.myUserId() == 0) {  
  4.         mPhoneGlobals = new PhoneGlobals(this);  
  5.         mPhoneGlobals.onCreate();  
  6.     }  
  7. }  
        接下来我们来看PhoneGlobals的onCreate过程:
  1. @PhoneGlobals  
  2. public void onCreate() {  
  3.     if (phone == null) {  
  4.         //创建Phone对象  
  5.         PhoneFactory.makeDefaultPhones(this);  
  6.         phone = PhoneFactory.getDefaultPhone();  
  7.   
  8.         //初始化CallManager  
  9.         mCM = CallManager.getInstance();  
  10.         mCM.registerPhone(phone);  
  11.   
  12.         //初始化NotificationMgr,用于状态栏通知  
  13.         notificationMgr = NotificationMgr.init(this);  
  14.   
  15.         //初始化CallController  
  16.         callController = CallController.init(this, callLogger, callGatewayManager);  
  17.   
  18.         //得到铃声控制  
  19.         ringer = Ringer.init(this, bluetoothManager);  
  20.         audioRouter = new AudioRouter(this, bluetoothManager, wiredHeadsetManager, mCM);  
  21.   
  22.         //初始化callCommandService  
  23.         callCommandService = new CallCommandService(this, mCM, callModeler, dtmfTonePlayer, audioRouter);  
  24.   
  25.         //初始化PhoneInterfaceManager  
  26.         phoneMgr = PhoneInterfaceManager.init(this, phone, callHandlerServiceProxy);  
  27.   
  28.         //初始化CallNotifer,响铃等动作在这里面完成  
  29.         notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor, bluetoothManager, callModeler);  
  30.   
  31.         //注册SIM卡状态监听  
  32.         IccCard sim = phone.getIccCard();  
  33.         if (sim != null) {  
  34.             sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);  
  35.         }  
  36.     }  
  37. }  
        从以上代码可以看出,PhoneGlobals的初始化过程中要先通过PhoneFactory的makeDefaultPhones()方法创建Phone对象,接着完成了一系列与Telephony相关的重要服务的初始化,比如CallManager、NotificationMgr、CallCommandService、PhoneInterfaceManager、CallNotifier等。
        我们现在只关心Phone对象的创建过程,也就是PhoneFactory的makeDefaultPhones过程:
  1. @PhoneFactory.java  
  2. public static void makeDefaultPhones(Context context) {  
  3.     makeDefaultPhone(context);  
  4. }  
  5. public static void makeDefaultPhone(Context context) {  
  6.     synchronized(Phone.class) {  
  7.         if (!sMadeDefaults) {  
  8.             //创建DefaultPhoneNotifier,负责通知Phone的状态  
  9.             sPhoneNotifier = new DefaultPhoneNotifier();  
  10.   
  11.             //得到当前的网络类型  
  12.             int networkMode = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);  
  13.             //根据当前网络类型来创建RILJ,负责Framework与RIL层交互  
  14.             sCommandsInterface = new RIL(context, networkMode, cdmaSubscription);  
  15.   
  16.             //创建UiccController并间接创建UiccCard、UiccCardApplication、IccFileHandler、IccRecords、CatService等服务  
  17.             UiccController.make(context, sCommandsInterface);  
  18.   
  19.             //根据当前的Phone类型创建不同的PhoneProxy  
  20.             int phoneType = TelephonyManager.getPhoneType(networkMode);  
  21.             if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {  
  22.                 //GSMPhone  
  23.                 sProxyPhone = new PhoneProxy(new GSMPhone(context, sCommandsInterface, sPhoneNotifier));  
  24.             } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {  
  25.                 switch (TelephonyManager.getLteOnCdmaModeStatic()) {  
  26.                     case PhoneConstants.LTE_ON_CDMA_TRUE:  
  27.                         //CDMALTEPhone  
  28.                         sProxyPhone = new PhoneProxy(new CDMALTEPhone(context, sCommandsInterface, sPhoneNotifier));  
  29.                         break;  
  30.                     case PhoneConstants.LTE_ON_CDMA_FALSE:  
  31.                     default:  
  32.                         //CDMAPhone  
  33.                         sProxyPhone = new PhoneProxy(new CDMAPhone(context, sCommandsInterface, sPhoneNotifier));  
  34.                         break;  
  35.                 }  
  36.             }  
  37.         }  
  38.     }  
  39. }  
        经过上面两段代码,我们看到了Phone对象的创建过程:
        1、先创建DefaultPhoneNotifier对象,该对象的作用是监听RIL层发过来的Phone状态变化;
        2、针对当前的网络类型创建不同的Java层RIL,即RILJ;
        3、拿到RILJ之后,就要利用DefaultPhoneNotifier和RILJ并根据当前的Phone类型(GSM/CDMA)来创建不同的Phone对象(GSMPhone/CDMALTEPhone/CDMAPhone);

        4、再用3中拿到的Phone创建PhoneProxy对象,这个代理对象才是可以直接使用的Phone对象;


三、Telephony实体对象本质


        从第二节的代码可以看到, 我们拿到的Phone对象(PhoneProxy)其实是一个“代理”的Phone对象,为什么要这样做呢?为什么不直接用GSMPhone或者CDMAPhone呢?
        我们应该考虑到,Android的通讯机制要解决的一个非常重要的问题就是,不同网络制式、不同运营商之间的差异。GSM的通讯协议和CDMA、LTE协议是存在很大差异的,他们的Modem不同、支持的网络命令、协议也都不同,因此Telephony必须将Phone对象抽象出来,构建一个屏蔽了不同协议的Phone对象,也就是这里的PhoneProxy。开发者无需关注当前用户使用的到底是GSMPhone还是CDMAPhone,当需要向Phone发送请求时,只需要用统一的命令对PhoneProxy发起请求即可,由PhoneProxy来完成指令的差异化处理。

        这个思想贯穿了整个Android的通讯机制,无论是RIL层、还是Telephony中,都能得到体现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《android telephony原理解析与开发指南》是杨青平编写的一本关于Android手机通讯系统的原理和开发指南的书籍。本书主要介绍了Android手机通讯系统的工作原理、架构和相关开发技术。 首先,本书对Android手机通讯系统的工作原理进行了深入解析。Android手机通讯系统是由Android操作系统及其上层应用程序组成的,通过多个模块协同工作实现电话通信功能。本书从系统启动过程、应用层协议、信令流程等方面详细介绍了Android手机通讯系统的运行原理。 其次,本书介绍了Android手机通讯系统的架构。Android手机通讯系统的架构主要包括RIL、Telephony Service和Phone App等重要组件。作者详细解释了各个组件的功能和相互之间的关系,帮助读者理解Android手机通讯系统的整体架构。 同时,本书还提供了Android手机通讯系统开发的指南。作者从配置环境、开发工具和开发步骤等方面详细介绍了Android手机通讯系统的开发过程。读者可以学习到如何使用Android SDK进行开发,如何编写Telephony Service和Phone App等应用程序。 《android telephony原理解析与开发指南》是一本系统而实用的Android手机通讯系统开发指南。通过阅读本书,读者可以全面了解Android手机通讯系统的原理和架构,掌握Android手机通讯系统开发的技巧和方法。作为一名Android开发者,这本书将成为您在Android手机通讯系统开发中的实用指南。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值