您的位置:首页 > 移动开发

数据业务建立流程之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过程:
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已经准备就绪。   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息