@DcTracker.java
public void setUserDataEnabled(boolean enable) {
Message msg = obtainMessage(DctConstants.CMD_SET_USER_DATA_ENABLE);
msg.arg1 = enable ? 1 : 0;
if (DBG) log("setDataEnabled: sendMessage: enable=" + enable);
sendMessage(msg);
}
调用打开/关闭数据接口后,DcTracker给自己发送msg(DctConstants.CMD_SET_USER_DATA_ENABLE),在handleMessage中处理调用onSetUserDataEnable,这里是具体的打开/关闭数据的操作。打开操作是onTrySetupData(),关闭操作是onCleanUpAllConnections()
private void onSetUserDataEnabled(boolean enabled) {
if (mDataEnabledSettings.isUserDataEnabled() != enabled) {
mDataEnabledSettings.setUserDataEnabled(enabled);
if (!getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
if (enabled) {
notifyOffApnsOfAvailability(Phone.REASON_ROAMING_ON);
} else {
notifyOffApnsOfAvailability(Phone.REASON_DATA_DISABLED);
}
}
mPhone.notifyUserMobileDataStateChanged(enabled);
// TODO: We should register for DataEnabledSetting's data enabled/disabled event and
// handle the rest from there.
if (enabled) {
reevaluateDataConnections();
onTrySetupData(Phone.REASON_DATA_ENABLED);//打开数据流量
} else {
onCleanUpAllConnections(Phone.REASON_DATA_SPECIFIC_DISABLED);//关闭数据流量
}
}
}
private boolean onTrySetupData(String reason) {
if (DBG) log("onTrySetupData: reason=" + reason);
setupDataOnConnectableApns(reason);
return true;
}
//此方法的作用为增加一个标志位,目的是连接失败时总是尝试重新连接
private void setupDataOnConnectableApns(String reason) {
setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
}
private void setupDataOnConnectableApns(String reason, RetryFailures retryFailures) {
...
for (ApnContext apnContext : mPrioritySortedApnContexts) {
if (VDBG) log("setupDataOnConnectableApns: apnContext " + apnContext);
if (apnContext.getState() == DctConstants.State.FAILED
|| apnContext.getState() == DctConstants.State.SCANNING) {
if (retryFailures == RetryFailures.ALWAYS) {
apnContext.releaseDataConnection(reason);
} else if (apnContext.isConcurrentVoiceAndDataAllowed() == false &&
mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
// RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
apnContext.releaseDataConnection(reason);
}
}
if (apnContext.isConnectable()) {
log("isConnectable() call trySetupData");
apnContext.setReason(reason);
trySetupData(apnContext);
}
}
}
遍历mPrioritySortedApnContexts,尝试每一种apn是否可连接,可连接就调用trySetupData(apnContext);进行实际连接操作。
mPrioritySortedApnContexts中的数值为,DcTracker初始化时构造方法调用initApnContexts(),生成的apn对象保存到mPrioritySortedApnContexts。