数据业务建立流程之APN参数的激活(原)
2015-11-03 10:33
453 查看
APN参数在前面《数据业务建立流程之常规APN参数的创建》一文中已经都被创建完毕并存入mAllApnSettings的数组中,但是这些APN参数默认都是没有被Enable的,只有当APN被Enable之后,该APN才可以被使用,下面我们就来看如何将一个APN参数激活。
APN的Enable是通过TelephonyNetworkFactory中的needNetworkFor()方法触发的,我们在《网络连接评分机制之NetworkFactory》文章中介绍过,当当前网络的评分比其他网络高时,就会通过needNetworkFor()方法触发当前网络的建立。比如当前WIFI断开时,如果发现数据网络是打开的,此时就会通过该方法激活数据流量,从而实现从WIFI到数据的转换过程。
而当needNetworkFor()被触发时,就会引发APN的Enable过程:
APN的Enable是通过TelephonyNetworkFactory中的needNetworkFor()方法触发的,我们在《网络连接评分机制之NetworkFactory》文章中介绍过,当当前网络的评分比其他网络高时,就会通过needNetworkFor()方法触发当前网络的建立。比如当前WIFI断开时,如果发现数据网络是打开的,此时就会通过该方法激活数据流量,从而实现从WIFI到数据的转换过程。
而当needNetworkFor()被触发时,就会引发APN的Enable过程:
protected void needNetworkFor(NetworkRequest networkRequest, int score) { //根据网络需求寻找合适APN ApnContext apnContext = apnContextForNetworkRequest(networkRequest); //Enable上网用的APN if (apnContext != null) apnContext.incRefCount(); }由于不同网络需求可能需要不同的APN参数,因此先要经过apnContextForNetworkRequest()来寻找合适的APN,对于上网来说,其寻找到的APN类型为TYPE_MOBILE,然后通过incRefCount()来Enable当前的APN:
@ApnContext.java public void incRefCount() { synchronized (mRefCountLock) { if (mRefCount++ == 0) { //设置Enable mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true); } } }这里需要用到DcTracker父类DcTrackerBase中的setEnabled()方法来将APN打开:
@DcTrackerBase.java protected void setEnabled(int id, boolean enable) { Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN); msg.arg1 = id; msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED); sendMessage(msg); }这里发送了一条EVENT_ENABLE_NEW_APN的消息,该消息将会在DcTrackerBase中handleMessage()中被处理:
@DcTrackerBase.java public void handleMessage(Message msg) { switch (msg.what) { case DctConstants.EVENT_ENABLE_NEW_APN: onEnableApn(msg.arg1, msg.arg2); break; } }这里的onEnableApn()在子类DcTracker中被覆盖:
@DcTracker.java protected void onEnableApn(int apnId, int enabled) { ApnContext apnContext = mApnContexts.get(apnIdToType(apnId)); if (apnContext == null) { loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext"); return; } //打开APN applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet()); }继续看applyNewState()过程,这里传递的第二个参数为true,第二个参数是从networkAttributes数组中读取的,默认都为true。
private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) { boolean cleanup = false; boolean trySetup = false; if (apnContext.isReady()) { //APN如果已经被Enable } else { if (enabled && met) { //APN需要被Enable if (apnContext.isEnabled()) { apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET); } else { //设置reason为REASON_DATA_ENABLED apnContext.setReason(Phone.REASON_DATA_ENABLED); } if (apnContext.getState() == DctConstants.State.FAILED) { apnContext.setState(DctConstants.State.IDLE); } trySetup = true; } } //Enable当前APN apnContext.setEnabled(enabled); //设置其mDependencyMet属性也为true apnContext.setDependencyMet(met); //清除当前连接 if (cleanup) cleanUpConnection(true, apnContext); //建立数据连接 if (trySetup) trySetupData(apnContext); }由于enabled、met两个参数此时都为true,因此将会设置APN的Reason为REASON_DATA_ENABLED,并且其mDataEnabled和mDependencyMet属性都为true:
public void setEnabled(boolean enabled) { mDataEnabled.set(enabled); } public void setDependencyMet(boolean met) { mDependencyMet.set(met); }再来看一下该APN参数isReady的判断:
public boolean isReady() { return mDataEnabled.get() && mDependencyMet.get(); }由此可知,以后当判断该APN是否isReady()时,将会得到true的状态,也就是说,当前APN已经准备就绪。
相关文章推荐
- Android基于APN获取手机号的方法
- AWS中国合作伙伴研讨会后记
- Android系统APN配置详解
- Android——4.2 - 3G移植之路之 APN (五)
- 3G调试笔记之发送AT命令和APN配置
- Android如何确定使用哪个apn
- 手机apn设置
- 水位监测系统总结 (唐山平升公司为例子)
- Android通过APN进行网络连接
- Android APN的设置问题 推荐
- Android APN的设置问题--进一步讨论 推荐
- java.lang.SecurityException: No permission to write APN settings问题原因
- Android APN的显示流程源代码分析
- Android 7.0 插卡后APN信息的加载流程、UI界面编辑APN的流程及Android中APN配置相关的漏洞
- Android6.0 APN
- APN基础常识
- Android添加APN配置后,OTA升级完成后,依然无法识别添加的APN
- Android工作杂项总结(APN,3G,i2c,SystemUI等)