Phone进程启动
<application android:name="PhoneApp"
android:persistent="true"
android:label="@string/phoneAppLabel"
android:icon="@mipmap/ic_launcher_phone"
android:allowBackup="false"
android:supportsRtl="true"
android:usesCleartextTraffic="true">
-
android:persistent=“true” 说明该app是开机过程中就可以启动的, 而且还是常驻进程。(Phone就象个后台进程一样,开机即运行并一直存在(如果异常退出,它会自动重启))
- PhoneApp是由ActivityManagerService启动的,具体执行可以参考ActivityManagerService类的SystemReady方法。
- PhoneApp
public class PhoneApp extends Application { PhoneGlobals mPhoneGlobals; TelephonyGlobals mTelephonyGlobals; public PhoneApp() { } @Override public void onCreate() { if (UserHandle.myUserId() == 0) { // We are running as the primary user, so should bring up the // global phone state. mPhoneGlobals = new PhoneGlobals(this); mPhoneGlobals.onCreate(); mTelephonyGlobals = new TelephonyGlobals(this); mTelephonyGlobals.onCreate(); } } }
主 要初始化了PhoneGlobals和TelephonyGlobals對象。
TelephonyGlobals主要是TTY的處理, 這裡跳過(沒有研究過)。
- PhoneFactory.java
-
public static void makeDefaultPhone(Context context) { //根据phoneCont创建Phone, RIL int numPhones = TelephonyManager.getDefault().getPhoneCount(); int[] networkModes = new int[numPhones]; sProxyPhones = new PhoneProxy[numPhones]; sCommandsInterfaces = new RIL[numPhones]; for (int i = 0; i < numPhones; i++) { //获取各个Phone对应的preferred network networkModes[i] = TelephonyManager.getIntAtIndex( context.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE , i); //创建RIL sCommandsInterfaces[i] = new RIL(context, networkModes[i], cdmaSubscription, i); } TelephonyPluginDelegate.getInstance().initSubscriptionController(context, sCommandsInterfaces); //UiccController 是对SIM卡管理的控制器,它通過UiccCard来更新SIM卡信息 mUiccController = UiccController.make(context, sCommandsInterfaces); //创建Phone对象和PhoneProxy代理对象,根据phoneType确认是CDMAPhone还是GMSPhone for (int i = 0; i < numPhones; i++) { PhoneBase phone = null; int phoneType = TelephonyManager.getPhoneType(networkModes[i]); if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { phone = TelephonyPluginDelegate.getInstance().makeGSMPhone(context, sCommandsInterfaces[i], sPhoneNotifier, i); } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { phone = TelephonyPluginDelegate.getInstance().makeCDMALTEPhone(context, sCommandsInterfaces[i], sPhoneNotifier, i); } sProxyPhones[i] = TelephonyPluginDelegate.getInstance().makePhoneProxy(phone); } }
Phone的代理模式:
• 接口 (Phone)
•目标对象 (PhoneBase)
• 代理对象(PhoneProxy)
-
代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。
从图中可以看到,之所以要使用代理模式,就是为了管理不同类型的Phone,访问者不需要知道Android系统想要什么类型的Phone,直接使用PhoneProxy对象就可。