马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目次
1、概述
2、原理
3、网络工厂
4、网络类型注册
5、网络链接哀求
6、网络评分机制
总结
8、附表
表1:代码路径
表2:网络能力
表3:网络透传能力
9、扩展:怎样举行第二路拨号并访问网络
9.1 拨号
9.2 访问
1、概述
ConnectivityService在 Android 系统中是一个核心的服务,它主要负责管理和监控网络连接的状态。这个服务是 Android 框架的一部分,为应用程序和系统服务提供了关于网络连接(如 wifi、mobile network、ethernet、bt-pan)的详细信息。
ConnectivityService作为管理员身份,每种网络都会去向它注册,网络的利用权全靠它来分配。并实现了网络评分机制确保了系统能够最出作优的网络连接,从而为用户提供更好的网络体验。
2、原理
相干类的功能说明如下:
- ConnectivityService是个服务,用来管理网络链接。
- ConnectivityManager是ConnectivityService的署理,署理意思是调用者不要关心具体接口的实现,只管调用,以是才设计此模式。以是ConnectivityManager作用是对外提供ConnectivityService的相干接口。
- TelephonyNetworkFatory是个移动的网络工厂,父类是NetworkFactory,用于SIM卡业务的数据链接。
- WifiNetworkFatory是个Wifi的网络工厂,父类是NetworkFactory,用于WIFI模块的数据链接。
- EthernetNetworkFatory是个以太网的网络工厂,父类是NetworkFactory,用于以太网业务的数据链接。
ConnectivityService链接服务从箭头来看分为2个流程,分别为注册和网络选择。
- 注册:见红色箭头,在设备开机时,相干的网络工厂会向ConnectivityService举行注册register,ConnectivityManager是个署理,ConnectivityService对外提供的接口都由ConnectivityManager提供,末了在register函数里通过调用registerNetworkProvider,ConnectivityService就拿到了各种类型的网络工厂,比如移动,Wifi,以太网等。
- 网络选择:见绿色箭头,假如存在多种网络的情况下,ConnectivityService根据evalRequest逻辑举行评分,分数高的网络工厂会优先利用,这叫做网络评分机制。从流程图可以看出,当应用调用哀求网络requestNetwork时(此函数是发起一个网络链接哀求),最终根据evalRequest函数找到分数最高的网络工厂然后调用它的needNetworkFor来完成网络链接哀求。
3、网络工厂
NetworkFactory网络工厂其实是通过工厂模式天生各自特有功能的网络类型。
上图的圆圈是网络工厂的相干类图,TelephonyNetworkFatory、WifiNetworkFatory、EthernetNetworkFatory网络类型继承NetworkFatory,NetworkFatory的重点override接口如下:
- needNetworkFor:哀求网络链接接口
- releaseNetworkFor:释放网络链接接口
- setScoreFilter(int score): 设置分数,除了初始评分外,各个网络的评分还会根据实时状态举行调解。
比方,以太网会根据网卡的up和down状态,把分值设置为70(当网卡up时)或0(当网卡down时)。Wi-Fi的分值还跟信号状态、当前数据速率等一系列因素有关,在WifiStateMachine.java的calculateWifiScore函数中举行盘算,初始盘算的基础分值为56,然后根据wifi网络的状态举行小的加减,末了假如分值大于60,就把分值设置为60。
- register(): 向ConnectivityService注册,这样ConnectivityService就能拿到各类型的网络。用于后面选择评分高的网络举行链接。
NetworkProvider直译是网络提供者,和对应的网络工厂绑定,用于告知ConnectivityService,方便异步调用网络提供者。
4、网络类型注册
在开机时,各网络类型通过调用register向ConnectivityService举行注册,函数代码如下:
- 1. public void register() {
- 2. if (mProvider != null) {
- 3. throw new IllegalStateException("A NetworkFactory must only be registered once");
- 4. }
- 5. if (DBG) log("Registering NetworkFactory");
- 6.
- 7. mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) {
- 8. @Override
- 9. public void onNetworkRequested(@NonNull NetworkRequest request, int score,
- 10. int servingProviderId) {
- 11. handleAddRequest(request, score, servingProviderId);
- 12. }
- 13.
- 14. @Override
- 15. public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
- 16. handleRemoveRequest(request);
- 17. }
- 18. };
- 19.
- 20. ((ConnectivityManager) mContext.getSystemService(
- 21. Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
- 22. }
复制代码 从如上代码可以看出,先创建一个NetworkProvider的对象mProvider,此对象之前说过,方便ConnectivityService举行异步调用,也就是NetworkProvider有相干的Messenger实现。
末了调用ConnectivityService的registerNetworkProvider函数完成注册,把NetworkProvider放到mNetworkProviderInfos这个成员数组里。其实ConnectivityService最终拿到的是NetworkFactory的NetworkProvider相干接口。
5、网络链接哀求
应用层怎样发起网络链接哀求,本文以TelephonyNetworkFatory为例说明。
ConnectivityManager对外提供了一个requestNetwork接口,以是应用层调用此接口即可。
- 1. NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
- 2. networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
- 3. networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- 4. // During an emergency call, and when we have cached the Active Sub Id, we set the
- 5. // Network Specifier so that the network request goes to the correct Sub Id
- 6. if (mNiHandler.getInEmergency() && mActiveSubId >= 0) {
- 7. if (DEBUG) Log.d(TAG, "Adding Network Specifier: " + Integer.toString(mActiveSubId));
- 8. networkRequestBuilder.setNetworkSpecifier(Integer.toString(mActiveSubId));
- 9. }
- 10. NetworkRequest networkRequest = networkRequestBuilder.build();
- 11. mConnMgr.requestNetwork(
- 12. networkRequest,
- 13. mSuplConnectivityCallback,
- 14. mHandler,
- 15. SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS);
复制代码 requestNetwork函数有2个重要的参数:
- NetworkRequest:网络哀求封装,如通过什么能力及什么方式透传。
addCapability:通过此函数设置网络能力,见表2。它用于向网络哀求添加特定的网络能力,具体来说,addCapability用于指定一个网络哀求所需或支持的网络特性,跟APN有关。本示例的网络能力是安全用户平面定位(SUPL),用于GPS辅助定位服务。
addTransportType:函数用于指定网络连接所利用的传输类型,见表3。传输类型决定了网络哀求所利用的底层传输技能,比方Wi-Fi、蜂窝数据等。本示例的传输类型是移动网络。
- NetworkCallback:网络哀求的回调,具体是ConnectivityManager.NetworkCallback,回调的接口有onAvailable,onLost,onUnavailable。
关于requestNetwork接下来怎样调用,请参考时序图,这里不再讲解。
6、网络评分机制
触发网络评分机制有很多多少种方法,如修改分数,下发网络哀求等。这些最终都会触发evalRequest函数的调用,代码如下:
- 1. private void evalRequest(NetworkRequestInfo n) {
- 2. if (VDBG) {
- 3. log("evalRequest");
- 4. log(" n.requests = " + n.requested);
- 5. log(" n.score = " + n.score);
- 6. log(" mScore = " + mScore);
- 7. log(" request.providerId = " + n.providerId);
- 8. log(" mProvider.id = " + mProvider.getProviderId());
- 9. }
- 10. if (shouldNeedNetworkFor(n)) {
- 11. if (VDBG) log(" needNetworkFor");
- 12. needNetworkFor(n.request, n.score);
- 13. n.requested = true;
- 14. } else if (shouldReleaseNetworkFor(n)) {
- 15. if (VDBG) log(" releaseNetworkFor");
- 16. releaseNetworkFor(n.request);
- 17. n.requested = false;
- 18. } else {
- 19. if (VDBG) log(" done");
- 20. } 21. }
复制代码 shouldNeedNetworkFor函数用于确认是否举行网络链接哀求,shouldReleaseNetworkFor函数用于释放网络链接哀求。
shouldNeedNetworkFor的函数代码如下,具体逻辑是:假如NetworkRequestInfo没有被requested过,而且其分值(n.score)小于当前NetworkFactory自己的分值(mScore),那么就说明,当前NetworkFactory所处的网络优先级高于其他网络的优先级,就会触发当前NetworkFactory所在网络的needNetworkFor()流程,也就是连接创建流程,并将标志NetworkRequestInfo.requested=true。当NetworkRequestInfo被requested过(也就是当前网络被needNetworkFor过),此时假如再次收到哀求,而且携带的新score大于当前NetworkFactory所处网络的mScore,那么就说明当前NetworkFactory所在网络优先级已经不是最高,需要将其releaseNetworkFor掉,并标志NetworkRequestInfo.requested=false。
- 1. private boolean shouldNeedNetworkFor(NetworkRequestInfo n) {
- 2. // If this request is already tracked, it doesn't qualify for need
- 3. return !n.requested
- 4. // If the score of this request is higher or equal to that of this factory and some
- 5. // other factory is responsible for it, then this factory should not track the request
- 6. // because it has no hope of satisfying it.
- 7. && (n.score < mScore || n.providerId == mProvider.getProviderId())
- 8. // If this factory can't satisfy the capability needs of this request, then it
- 9. // should not be tracked.
- 10. && n.request.canBeSatisfiedBy(mCapabilityFilter)
- 11. // Finally if the concrete implementation of the factory rejects the request, then
- 12. // don't track it.
- 13. && acceptRequest(n.request, n.score);
- 14. }
复制代码 总结
本文大概讲了ConnectivityService框架及接口利用说明,涉及的还不是很深。后面有问题再具体总结分析这块的内容。
8、附表
表1:代码路径
路径
| frameworks\opt\telephony\src\java\com\android\internal\telephony\dataconnection\TelephonyNetworkFactory.java
frameworks\libs\net\common\src_servicescommon\android\net\NetworkFactory.java
frameworks\base\core\java\android\net\NetworkCapabilities.java
frameworks\base\core\java\android\net\NetworkRequest.java
frameworks\base\core\java\android\net\ConnectivityManager.java
frameworks\base\core\java\android\net\ Network.java
frameworks\base\core\java\android\net\ NetworkProvider.java
frameworks\base\services\core\java\com\android\server\ConnectivityService.java
frameworks\opt\net\ethernet\java\com\android\server\ethernet\ EthernetNetworkFactory.java
| 表2:网络能力
NetworkCapabilities
| ApnSetting
| 能力说明
| NET_CAPABILITY_MMS
| TYPE_MMS
| 多媒体消息服务(MMS),用于发送和接收彩信。
| NET_CAPABILITY_SUPL
| TYPE_SUPL
| 安全用户平面定位(SUPL),用于GPS辅助定位服务。
| NET_CAPABILITY_DUN
| TYPE_DUN
| 拨号上网(DUN),允许设备通过移动网络为其他设备提供网络连接。
| NET_CAPABILITY_FOTA
| TYPE_FOTA
| 固件空中升级(FOTA),允许设备通过移动网络接收固件更新。
| NET_CAPABILITY_IMS
| TYPE_IMS
| IP多媒体子系统(IMS),用于支持VoIP等多媒体通信服务。
| NET_CAPABILITY_CBS
| TYPE_CBS
| 小区广播服务(CBS),用于向手机用户发送小区内的短消息。
| NET_CAPABILITY_IA
| TYPE_IA
| 这个名称不太常见,大概表示某种特定类型的网络访问或功能。
| NET_CAPABILITY_EIMS
| TYPE_EMERGENCY
| 紧急IMS,大概用于紧急情况下的多媒体通信。
| NET_CAPABILITY_INTERNET
| TYPE_DEFAULT
| 表示网络可以访问互联网。
| NET_CAPABILITY_WIFI_P2P
|
| Wi-Fi直连(P2P),允许设备之间直接通过Wi-Fi举行通信,无需接入点。
| NET_CAPABILITY_RCS
|
| 丰富的呼唤服务(RCS),用于增强语音呼唤的功能,如视频通话、即时消息等。
| NET_CAPABILITY_XCAP
|
| XML设置访问协议(XCAP),一种用于存储和检索XML文档的协议。
| NET_CAPABILITY_NOT_METERED
|
| 表示网络流量不计费。
| NET_CAPABILITY_NOT_RESTRICTED
|
| 表示网络没有访问限制。
| NET_CAPABILITY_TRUSTED
|
| 表示网络是可信的。
| 表3:网络透传能力
TransportType
| 能力名称
| 能力说明
| TRANSPORT_CELLULAR:
| 蜂窝数据网络
| 如2G、3G、4G(LTE)、5G等移动网络。
| TRANSPORT_WIFI
| Wi-Fi网络
| 通过无线局域网连接到互联网。
| TRANSPORT_BLUETOOTH
| 蓝牙网络
| 固然蓝牙通常不消于互联网连接,但在某些特定场景下(如蓝牙PAN)大概用作数据传输。
| TRANSPORT_ETHERNET
| 以太网网络
| 这通常指的是有线网络连接,但在Android设备上较为稀有,因为移动设备主要利用无线连接。
| TRANSPORT_VPN
| 捏造私人网络(VPN)
| 这是一种通过公共网络(如互联网)创建加密通道的技能,用于在远程服务器上安全地发送和接收数据。
| 9、扩展:怎样举行第二路拨号并访问网络
9.1 拨号
在利用移动网络举行第二跑拨号时,要注意不能与当前的apn雷同,比如当前是default的apn,那么第二路只能利用其他apn类型拨号了,否则会报如下错误。
ConnectivityService: NetReassign [53 : null → 100]
利用APN为mms的拨号示例代码如下:
- 1. import android.net.ConnectivityManager;
- 2. import android.net.Network;
- 3. import android.net.NetworkCapabilities;
- 4. import android.net.NetworkInfo;
- 5. import android.net.NetworkRequest;
- 6.
- 7. private ConnectivityManager.NetworkCallback createConnectivityCallback(){
- 8. return new ConnectivityManager.NetworkCallback() {
- 9. @Override
- 10. public void onAvailable(Network network) {
- 11. // Specific to a change to a SUPL enabled network becoming ready
- 12. Log.d(LOG_TAG, "test network connection available.");
- 13. }
- 14.
- 15. @Override
- 16. public void onLost(Network network) {
- 17. Log.d(LOG_TAG, "test network connection lost.");
- 18. }
- 19.
- 20. @Override
- 21. public void onUnavailable() {
- 22. Log.d(LOG_TAG, "test network connection request timed out.");
- 23. // Could not setup the connection to the network in the specified time duration.
- 24.
- 25. }
- 26. };
- 27. }
- 28. //发起移动网络拨号
- 29. private void startSecDataCall()
- 30. {
- 31. ConnectivityManager mTConnMgr;
- 32. ConnectivityManager.NetworkCallback mConnectivityCallback = createConnectivityCallback();
- 33. mTConnMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
- 34.
- 35. NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
- 36. networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
- 37. networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- 38.
- 39. NetworkRequest networkRequest = networkRequestBuilder.build();
- 40. mTConnMgr.requestNetwork(
- 41. networkRequest,
- 42. mConnectivityCallback,
- 43. 20 * 1000);
- 44. }
复制代码
拨号成功后,可利用ifconfig指令查询网卡有没有辨认出来。

9.2 访问
利用第二路访问网络代码:
- 1. import java.net.URL;
- 2. import java.net.MalformedURLException;
- 3. import java.io.IOException;
- 4. import java.net.URLConnection;
- 5. import java.io.ByteArrayOutputStream;
- 6.
- 7. private String getTest(URLConnection urlConnection) throws IOException {
- 8. //URL url = new URL(pacUri.toString());
- 9. //URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
- 10. long MAX_PAC_SIZE = 20 * 1000 * 1000;
- 11. long contentLength = -1;
- 12. try {
- 13. contentLength = Long.parseLong(urlConnection.getHeaderField("Content-Length"));
- 14. } catch (NumberFormatException e) {
- 15. // Ignore
- 16. }
- 17. if (contentLength > MAX_PAC_SIZE) {
- 18. throw new IOException("PAC too big: " + contentLength + " bytes");
- 19. }
- 20. ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- 21. byte[] buffer = new byte[1024];
- 22. int count;
- 23. while ((count = urlConnection.getInputStream().read(buffer)) != -1) {
- 24. bytes.write(buffer, 0, count);
- 25. if (bytes.size() > MAX_PAC_SIZE) {
- 26. throw new IOException("PAC too big");
- 27. }
- 28. }
- 29. Log.d(LOG_TAG, "bytes.size() = " + bytes.size());
- 30. return bytes.toString();
- 31. }
- 32.
- 33. private ConnectivityManager.NetworkCallback createConnectivityCallback(){
- 34. return new ConnectivityManager.NetworkCallback() {
- 35. @Override
- 36. public void onAvailable(Network network) {
- 37. // Specific to a change to a SUPL enabled network becoming ready
- 38. Log.d(LOG_TAG, "test network connection available");
- 39. URL mUrl;
- 40.
- 41. try {
- 42. mUrl = new URL("https://www.baidu.com/");
- 43. //Log.d(LOG_TAG, "test network mUrl = ", mUrl);
- 44. getTest(network.openConnection(mUrl));
- 45. } catch (IOException e) {
- 46. //throw new MalformedURLException("open()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
- 47. Log.d(LOG_TAG, "test network 11");
- 48. }
- 49. }
- 50.
- 51. @Override
- 52. public void onLost(Network network) {
- 53. Log.d(LOG_TAG, "test network connection lost.");
- 54. }
- 55.
- 56. @Override
- 57. public void onUnavailable() {
- 58. Log.d(LOG_TAG, "test network connection request timed out.");
- 59. // Could not setup the connection to the network in the specified time duration.
- 60.
- 61. }
- 62. };
- 63. }
复制代码
可通过检察对应网卡的RX TX属性,确认是否从该网卡收发,见如下图。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |