这篇给出是数据开关状态变化引起网络状态的改变的代码流程,数据开关是指设置 -->无线网络设置 -->移动设置 -->是否启用数据的那个选项,选中表示启用,当然不同手机的中文翻译可能不同,不过不影响理解。先贴张图,图中就是设置数据开关所走的代码流程了。
这张图并不是完整的,其实在上图最后的 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端可以处理的。
上网相关的部分暂时就这些了,写得很简单,当然了解的也不深是主要原因,不过这些也包括主要的上网流程了。以后有机会再慢慢补充,欢迎指正。