数据业务建立流程之APN参数的激活
2017-09-25 14:04
369 查看
APN参数在前面《数据业务建立流程之常规APN参数的创建》一文中已经都被创建完毕并存入mAllApnSettings的数组中,但是这些APN参数默认都是没有被Enable的,只有当APN被Enable之后,该APN才可以被使用,下面我们就来看如何将一个APN参数激活。
APN的Enable是通过TelephonyNetworkFactory中的needNetworkFor()方法触发的,我们在《网络连接评分机制之NetworkFactory》文章中介绍过,当当前网络的评分比其他网络高时,就会通过needNetworkFor()方法触发当前网络的建立。比如当前WIFI断开时,如果发现数据网络是打开的,此时就会通过该方法激活数据流量,从而实现从WIFI到数据的转换过程。
而当needNetworkFor()被触发时,就会引发APN的Enable过程:
[java]
view plain
copy
print?
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
//根据网络需求寻找合适APN
ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
//Enable上网用的APN
if (apnContext != null) apnContext.incRefCount();
}
[java]
view plain
copy
print?
@ApnContext.java
public void incRefCount() {
synchronized (mRefCountLock) {
if (mRefCount++ == 0) {
//设置Enable
mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true);
}
}
}
[java]
view plain
copy
print?
@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);
}
[java]
view plain
copy
print?
@DcTrackerBase.java
public void handleMessage(Message msg) {
switch (msg.what) {
case DctConstants.EVENT_ENABLE_NEW_APN:
onEnableApn(msg.arg1, msg.arg2);
break;
}
}
[java]
view plain
copy
print?
@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());
}
[java]
view plain
copy
print?
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);
}
[java]
view plain
copy
print?
public void setEnabled(boolean enabled) {
mDataEnabled.set(enabled);
}
public void setDependencyMet(boolean met) {
mDependencyMet.set(met);
}
[java]
view plain
copy
print?
public boolean isReady() {
return mDataEnabled.get() && mDependencyMet.get();
}
APN的Enable是通过TelephonyNetworkFactory中的needNetworkFor()方法触发的,我们在《网络连接评分机制之NetworkFactory》文章中介绍过,当当前网络的评分比其他网络高时,就会通过needNetworkFor()方法触发当前网络的建立。比如当前WIFI断开时,如果发现数据网络是打开的,此时就会通过该方法激活数据流量,从而实现从WIFI到数据的转换过程。
而当needNetworkFor()被触发时,就会引发APN的Enable过程:
[java]
view plain
copy
print?
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
//根据网络需求寻找合适APN
ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
//Enable上网用的APN
if (apnContext != null) apnContext.incRefCount();
}
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:
[java]
view plain
copy
print?
@ApnContext.java
public void incRefCount() {
synchronized (mRefCountLock) {
if (mRefCount++ == 0) {
//设置Enable
mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true);
}
}
}
@ApnContext.java public void incRefCount() { synchronized (mRefCountLock) { if (mRefCount++ == 0) { //设置Enable mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true); } } }这里需要用到DcTracker父类DcTrackerBase中的setEnabled()方法来将APN打开:
[java]
view plain
copy
print?
@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);
}
@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()中被处理:
[java]
view plain
copy
print?
@DcTrackerBase.java
public void handleMessage(Message msg) {
switch (msg.what) {
case DctConstants.EVENT_ENABLE_NEW_APN:
onEnableApn(msg.arg1, msg.arg2);
break;
}
}
@DcTrackerBase.java public void handleMessage(Message msg) { switch (msg.what) { case DctConstants.EVENT_ENABLE_NEW_APN: onEnableApn(msg.arg1, msg.arg2); break; } }这里的onEnableApn()在子类DcTracker中被覆盖:
[java]
view plain
copy
print?
@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());
}
@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。
[java]
view plain
copy
print?
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);
}
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:
[java]
view plain
copy
print?
public void setEnabled(boolean enabled) {
mDataEnabled.set(enabled);
}
public void setDependencyMet(boolean met) {
mDependencyMet.set(met);
}
public void setEnabled(boolean enabled) { mDataEnabled.set(enabled); } public void setDependencyMet(boolean met) { mDependencyMet.set(met); }再来看一下该APN参数isReady的判断:
[java]
view plain
copy
print?
public boolean isReady() {
return mDataEnabled.get() && mDependencyMet.get();
}
public boolean isReady() { return mDataEnabled.get() && mDependencyMet.get(); }由此可知,以后当判断该APN是否isReady()时,将会得到true的状态,也就是说,当前APN已经准备就绪。
相关文章推荐
- 数据业务建立流程之APN参数的激活
- 数据业务建立流程之APN参数的激活
- 数据业务建立流程之APN参数的激活(原)
- 数据业务建立流程之常规APN参数的创建
- 数据业务建立流程之常规APN参数的创建
- 数据业务建立流程之常规APN参数的创建(原)
- 【Android 数据业务解析】APN参数创建
- 数据业务建立流程之DcTracker创建过程
- Android6.0 Telephony Frameworks之数据业务建立流程
- 数据业务建立流程之发起网络连接过程
- 数据业务建立流程之发起网络连接过程(原)
- 四、 Android 数据业务APN参数的创建
- 数据业务建立流程之DcTracker创建过程
- 五、 数据业务APN参数的开机默认使能
- 数据业务建立流程之发起网络连接过程
- 数据业务建立流程之DcTracker创建过程(原)
- 数据业务建立流程之DcTracker创建过程
- 数据业务建立流程之发起网络连接过程
- JFlow&CCFlow流程引擎的业务数据与流程数据同步的操作步骤.
- 一步一步建立我的MIS系统:业务流程处理:BusinessObject