telephony framework中的代理模式

来源:互联网 发布:批发零售软件 编辑:程序博客网 时间:2024/06/05 17:10

Android telephony framework中有Phone.java,PhoneBase.java, GsmPhone.java(或者CdmaPhone), PhoneProxy.java

其中Phone是接口类,剩余三个类都实现了Phone接口,只不过是作用不一样。PhoneBase实现了一些通用的接口;GsmPhone和CDMAPhone,两者层次是对等的,只不过一个实现符合Gsm要求,另一个实现符合cdma的要求;PhoneProxy从名字就能看出是代理类。app层获取的Phone对象实际的类型就是PhoneProxy。

代理模式举例在百度上到处是,不过阐述该模式到底有啥好处的比较少,从网上我看到几种说法:

1.代码解耦。如日志代码可以加入到代理类中,那么日志代码就不会污染实现类的代码,切面编程就是这种思想。

2.系统扩展。写代理类是因为无法修改实现类或者无法继承实现类,设想我用的是三方库,没法修改代码,又要做些修改,用代理模式不错。

3.对象很大或者需要很长时间才能构造完毕的情况。通常见于网络程序,例如一副很大的图片载入时间很长,这时可以用代理表示图片请求,实现类表示正真的下载过程;还有懒加载,当有很多项要加载的时候,全部下载是很费资源的,可以用proxy占位,当需要的时候才正真加载。

本人没有搞过网络编程,虽然写java但是没写过SSH架构的东西,不大好理解动态代理,而且Android源码对于大多数手机厂商是可随意修改的,也不存在无法修改实现类的这个原因。而且见代码片段:

frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneProxy.java

 @Override    public ServiceState getServiceState() {        return mActivePhone.getServiceState();    }    @Override    public CellLocation getCellLocation() {        return mActivePhone.getCellLocation();    }    /**     * @return all available cell information or null if none.     */    @Override    public List<CellInfo> getAllCellInfo() {        return mActivePhone.getAllCellInfo();    }    /**     * {@inheritDoc}     */    @Override    public void setCellInfoListRate(int rateInMillis) {        mActivePhone.setCellInfoListRate(rateInMillis);    }    @Override    public PhoneConstants.DataState getDataConnectionState() {        return mActivePhone.getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);    }    @Override    public PhoneConstants.DataState getDataConnectionState(String apnType) {        return mActivePhone.getDataConnectionState(apnType);    }    @Override    public DataActivityState getDataActivityState() {        return mActivePhone.getDataActivityState();    }    @Override    public Context getContext() {        return mActivePhone.getContext();    }
基本所有的方法都是直接调用实现类mActivePhone的同名同参方法,没有加任何逻辑代码,那么使用代理模式是为了啥?

其实在PhoneProxy的构造函数中:

        mCommandsInterface.registerForVoiceRadioTechChanged(                             this, EVENT_VOICE_RADIO_TECH_CHANGED, null);
向ril注册了监听网络制式变化的消息

        case EVENT_VOICE_RADIO_TECH_CHANGED:            ...            phoneObjectUpdater(newVoiceTech);            ...            break;
消息处理中调用phoneObjectUpdater

  private void phoneObjectUpdater(int newVoiceRadioTech) {        ...        deleteAndCreatePhone(newVoiceRadioTech);        ...               mIccSmsInterfaceManager.updatePhoneObject((PhoneBase) mActivePhone);        mIccPhoneBookInterfaceManagerProxy.setmIccPhoneBookInterfaceManager(mActivePhone                .getIccPhoneBookInterfaceManager());        mPhoneSubInfoProxy.setmPhoneSubInfo(mActivePhone.getPhoneSubInfo());        mCommandsInterface = ((PhoneBase)mActivePhone).mCi;        mIccCardProxy.setVoiceRadioTech(newVoiceRadioTech);        ... }
删除了原有的Phone对象,依据新的网络制式建立了新的Phone对象,然后更新各个代理类的实现类。那么telephony framework中的代理类作用其实就是可以切换实现类而对上层app没影响(消除了实现类变化对使用代理类代码的影响),试想如果上层app直接使用GsmPhone或者CdmaPhone,那么网络制式切换造成的影响可就很大了。

较早的时候切换网络制式这种现象是很罕见的,只有电信国际漫游在某些国家会由cdma切换到gsm,不过现在到处是全网通机器,这种现象比较普遍了。

0 0