这篇给出是数据开关状态变化引起网络状态的改变的代码流程,数据开关是指设置 -->无线网络设置 -->移动设置 -->是否启用数据的那个选项,选中表示启用,当然不同手机的中文翻译可能不同,不过不影响理解。先贴张图,图中就是设置数据开关所走的代码流程了。
这张图并不是完整的,其实在上图最后的 MobileDataStateTracker.java的reconnect()方法之后的流程就和Apn切换上网的代码流程(详见android 上网 (一)-- apn切换拨号)是一样的了,那里有个setEnableApn()方法,这样就两条路就汇合了,所以在此并未画出。
在android源码中还有一种应用主动拨号的上网,比如信息,代码在TransactionService.java里beginMmsConnectivity()方法里,看下代码吧。
protected int beginMmsConnectivity() throws IOException {
// Take a wake lock so we don't fall asleep before the message is downloaded.
createWakeLock();
int result = mConnMgr.startUsingNetworkFeature(
ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
//省去log信息......
switch (result) {
case Phone.APN_ALREADY_ACTIVE:
case Phone.APN_REQUEST_STARTED:
acquireWakeLock();
return result;
}
throw new IOException("Cannot establish MMS connectivity");
}
在这里看startUsingNetworkFeature()方法,代码走到ConnectivityManager.java这个类了,这个类里的代码很少,关键的在ConnectivityService.java里的同名startUsingNetworkFeature()方法里,ConnectivityManager.java那个类只是对外接口,干活的代码在这里
public int startUsingNetworkFeature(int networkType, String feature,
IBinder binder) {
enforceChangePermission();
if (!ConnectivityManager.isNetworkTypeValid(networkType) ||mNetConfigs[networkType] == null) {
return Phone.APN_REQUEST_FAILED;
}
FeatureUser f = new FeatureUser(networkType, feature, binder);
int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
if (mProtectedNetworks.contains(usedNetworkType)) {
enforceConnectivityInternalPermission();
}
NetworkStateTracker network = mNetTrackers[usedNetworkType];
if (network != null) {
Integer currentPid = new Integer(getCallingPid());
if (usedNetworkType != networkType) {
NetworkInfo ni = network.getNetworkInfo();
if (ni.isAvailable() == false) {
if (DBG) log("special network not available");
if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
return Phone.APN_TYPE_NOT_AVAILABLE;
} else {
// else make the attempt anyway - probably giving REQUEST_STARTED below
}
}
//省略很多的代码.........
if ((ni.isConnectedOrConnecting() == true) &&
!network.isTeardownRequested()) {
if (ni.isConnected() == true) {
// add the pid-specific dns
handleDnsConfigurationChange(usedNetworkType);
if (VDBG) log("special network already active");
return Phone.APN_ALREADY_ACTIVE;
}
if (VDBG) log("special network already connecting");
return Phone.APN_REQUEST_STARTED;
}
network.reconnect();//看到了吧,reconnect()又来了
return Phone.APN_REQUEST_STARTED;
} else {
synchronized(this) {
mFeatureUsers.add(f);
if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {
mNetRequestersPids[usedNetworkType].add(currentPid);
}
}
return -1;
}
}
return Phone.APN_TYPE_NOT_AVAILABLE;
}
后面的路又一样了,到这里我们可以发现三种不同的上网起点最后的路都是一样,殊途同归,这是必然的。对于上网的问题,我们会去检查链路的状态看各状态是否正确和DNS的设置是否正确,还有有时候也需要关注是否网络侧主动断网,这种断网是没什么道理的,至少不是AP端可以处理的。
上网相关的部分暂时就这些了,写得很简单,当然了解的也不深是主要原因,不过这些也包括主要的上网流程了。以后有机会再慢慢补充,欢迎指正。