为了ConnectivityService便于统一管理,每一个具备提供网络服务的对象都需要创建一个NetworkFactory的子类对象,并利用该对象注册自己,以及提供自己的分值。
@NetworkFactory.java /** * A NetworkFactory is an entity that creates NetworkAgent objects. * The bearers register with ConnectivityService using {@link #register} and * their factory will start receiving scored NetworkRequests. NetworkRequests * can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by * overridden function. All of these can be dynamic - changing NetworkCapabilities * or score forces re-evaluation of all current requests. * @hide **/ public class NetworkFactory extends Handler {}这里的注释介绍了该类的基本作用和注册方法,其开头的部分介绍到,该对象可以用来创建NetworkAgent,而结尾的hide标明该类是隐藏类,也就是说 第三方应用无法使用,也就意味着第三方应用是无法承担网络连接的责任。
//将当前网络注册到ConnectivityService public void register() { } //处理网络请求,用于打开或者释放当前连接 private void handleAddRequest(NetworkRequest request, int score) {} //更新当前网络的分值 public void setScoreFilter(int score) {}以上三个是最重要的方法,在接下来的分析中将会多次看到他们的调用。还有几个比较特殊的方法:
protected void startNetwork() { } protected void stopNetwork() { } protected void needNetworkFor(NetworkRequest networkRequest, int score) { } protected void releaseNetworkFor(NetworkRequest networkRequest) { }这些方法都是protected属性,他们的作用就是在评分后,决定当前网络被激活或者释放,因此 一般都会在子类中被覆盖。
属性和方法介绍到这里,下面介绍该对象的使用。
@DcTracker.java public DcTracker(PhoneBase p) { ConnectivityManager cm = (ConnectivityManager)p.getContext().getSystemService( Context.CONNECTIVITY_SERVICE); mNetworkFilter = new NetworkCapabilities(); mNetworkFilter.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); mNetworkFilter.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); //初始化NetworkFactory的子类TelephonyNetworkFactory mNetworkFactory = new TelephonyNetworkFactory(this.getLooper(), p.getContext(), "TelephonyNetworkFactory", mNetworkFilter); //设置当前网络的分数为50分 mNetworkFactory.setScoreFilter(50); mNetworkFactoryMessenger = new Messenger(mNetworkFactory); //把当前的NetworkFactory注册到ConnectivityService中 cm.registerNetworkFactory(mNetworkFactoryMessenger, "Telephony"); }从DcTracker中我们发现, 该网络环境的NetworkFactory其实是TelephonyNetworkFactory,他的定义:
@DcTracker.java private class TelephonyNetworkFactory extends NetworkFactory { public TelephonyNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities nc) { super(l, c, TAG, nc); } @Override protected void needNetworkFor(NetworkRequest networkRequest, int score) { //进行数据连接的激活 ApnContext apnContext = apnContextForNetworkRequest(networkRequest); if (apnContext != null) apnContext.incRefCount(); } @Override protected void releaseNetworkFor(NetworkRequest networkRequest) { //数据连接释放 ApnContext apnContext = apnContextForNetworkRequest(networkRequest); if (apnContext != null) apnContext.decRefCount(); } }以上就是数据连接的NetworkFactory初始化过程,正如我们之前所说,要使用NetworkFactory只需要三个步骤:
3、将当前NetworkFactory注册到ConnectivityService
@WifiStateMachine.java class DefaultState extends State { @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_BOOT_COMPLETED: String countryCode = mPersistedCountryCode; checkAndSetConnectivityInstance(); //创建WIFI的NetworkFactory子类 mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext, NETWORKTYPE, mNetworkCapabilitiesFilter); //设置WIFI网络分数为60 mNetworkFactory.setScoreFilter(60); //注册 mCm.registerNetworkFactory(new Messenger(mNetworkFactory), NETWORKTYPE); break; default: break; } return HANDLED; } }来看WIFI的NetworkFactory:
private class WifiNetworkFactory extends NetworkFactory { public WifiNetworkFactory(Looper l, Context c, String TAG, NetworkCapabilities f) { super(l, c, TAG, f); } protected void startNetwork() { } protected void stopNetwork() { } }
其过程与数据连接中创建NetworkFactory的过程是一样的,并且WIFI的NetworkFactory的实现更加简单,虽然覆盖了父类中的两个protected方法,但是实际上该方法在WIFI中也是空的。这说明,WIFI无法通过NetworkFactory释放自己的链接(而可以通过NetworkAgent来释放)。
@ConnectivityService.java public void registerNetworkFactory(Messenger messenger, String name) { enforceConnectivityInternalPermission(); //NetworkFactory在ConnectivityService内部是以NetworkFactoryInfo形式存在的 NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); }从这里我们看到,在ConnectivityService中,利用当前的NetworkFactory创建NetworkFactoryInfo对象,该对象保存了当前网络连接的name、Messenger对象,并且为其创建了AsyncChannel。
private class InternalHandler extends Handler { public void handleMessage(Message msg) { NetworkInfo info; switch (msg.what) { case EVENT_REGISTER_NETWORK_FACTORY: { handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); break; } } } }继续:
private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { mNetworkFactoryInfos.put(nfi.messenger, nfi); nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); }到这里我们发现, ConnectivityService将当前的NetworkFactoryInfo保存到mNetworkFactoryInfos中,然后向当前的NetworkFactory发起AsyncChannel 单向通道申请( AsyncChannel相关介绍见这里)。
@ConnectivityService.java private class NetworkStateTrackerHandler extends Handler { public void handleMessage(Message msg) { NetworkInfo info; switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { handleAsyncChannelHalfConnect(msg); break; } } } }处理单向连接:
private void handleAsyncChannelHalfConnect(Message msg) { AsyncChannel ac = (AsyncChannel) msg.obj; if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { for (NetworkRequestInfo nri : mNetworkRequests.values()) { if (nri.isRequest == false) continue; NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, (nai != null ? nai.getCurrentScore() : 0), 0, nri.request); } } else { } } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { } }在这里,ConnectivityService通过AsyncChannel通道向当前的NetworkFactory发起CMD_REQUEST_NETWORK的请求,需要注意的是,该请求所附带的第二个参数选择,由于当前处于初始化阶段,因此当前的mNetworkForRequestId中为空,也就是说此时传递的第二个参数必然为0。
@NetworkFactory.java public void handleMessage(Message msg) { switch (msg.what) { case CMD_REQUEST_NETWORK: { handleAddRequest((NetworkRequest)msg.obj, msg.arg1); break; } } }继续:
private void handleAddRequest(NetworkRequest request, int score) { NetworkRequestInfo n = mNetworkRequests.get(request.requestId); if (n == null) { n = new NetworkRequestInfo(request, score); mNetworkRequests.put(n.request.requestId, n); } else { n.score = score; } evalRequest(n); }在这里由于是第一次接收到CMD_REQUEST_NETWORK的请求,因此将会在NetworkFactory中创建NetworkRequestInfo的对象,然后进入网络评价过程:
private void evalRequest(NetworkRequestInfo n) { if (n.requested == false && n.score < mScore && n.request.networkCapabilities.satisfiedByNetworkCapabilities( mCapabilityFilter) && acceptRequest(n.request, n.score)) { needNetworkFor(n.request, n.score); n.requested = true; } else if (n.requested == true && (n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities( mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) { releaseNetworkFor(n.request); n.requested = false; } }该逻辑就是整个网络评价系统最关键的地方,如果NetworkRequestInfo没有被requested过,并且其分值(n.score)小于当前NetworkFactory自己的分值(mScore),那么就说明,当前NetworkFactory所处的网络优先级高于其他网络的优先级,就会触发当前NetworkFactory所在网络的needNetworkFor()流程,也就是连接建立流程,并将标记NetworkRequestInfo.requested=true。