Phone 框架的初步分析(Call )

 

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">
  1. android:persistent=“true” 说明该app是开机过程中就可以启动的, 而且还是常驻进(Phone就象个后台进程一样,开机即运行并一直存在(如果异常退出,它会自动重启)
  2. 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();
            }
        }
    }
    

     

    主     要初始化了PhoneGlobalsTelephonyGlobals對象。

                    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对象就可。    

猜你喜欢

转载自bacalli.iteye.com/blog/2311012