在开机时,各个提供网络连接的对象需要向ConnectivityService注册自己,并把自己所提供的网络的分值告诉ConnectivityService。
从其继承关系看到,他的本质是一个Handler类。
然后我们来简单介绍一下该类提供的几个重要方法:
简单介绍一下DcTracker,他是数据网络的提供者,承担着APN参数选择、数据业务建立与释放等作用。
在DcTracker初始化时将会初始化数据的NetworkFactory对象:
1、初始化NetworkFactory子类,并实现其中的protected方法,他们的作用就是在网络评分时决定激活或者释放当前的网络连接。
2、设置当前网络的分值
同样的,在WIFI检测到系统初始化完毕的时候,将会创建自己的NetworkFactory并向ConnectivityService注册:
虽然注册的过程是向ConnectivityManager申请的,但是从前一节《 Framework中的连接管理机制》中我们知道,ConnectivityManager将会把相应请求交给ConnectivityService来处理,对于注册的申请,也是传递到ConnectivityService中的registerNetworkFactory()来处理的:
接下来继续看注册过程:
申请成功时,将会向当前的mTrackerHandler发送CMD_CHANNEL_HALF_CONNECTED消息:
我们接下来看NetworkFactory收到该请求时的处理:
当NetworkRequestInfo被requested过(也就是当前网络被needNetworkFor过),此时如果再次收到请求,并且携带的新score大于当前NetworkFactory所处网络的mScore,那么就说明当前NetworkFactory所在网络优先级已经不是最高,需要将其releaseNetworkFor掉,并标记NetworkRequestInfo.requested=false。
对于初始化流程来说,由于NetworkRequestInfo是刚才在handleAddRequest新创建的,所以其requested状态必然为false,而且我们前面提到,ConnectivityService发送CMD_REQUEST_NETWORK时携带的分值参数为0,并且对于数据网络来说,其mScore=50,因此此时的判定状态将会是:n.requested=false AND n.score < mScore。
也就是说,对于数据网络环境初始化过程来说,将会满足第一个if判断,进入needNetworkFor流程,也就是触发数据网络的建立。
至此,NetworkFactory注册流程结束。
为了ConnectivityService便于统一管理,每一个具备提供网络服务的对象都需要创建一个NetworkFactory的子类对象,并利用该对象注册自己,以及提供自己的分值。
一、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 {}
@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标明该类是隐藏类,也就是说
第三方应用无法使用,也就意味着第三方应用是无法承担网络连接的责任。
从其继承关系看到,他的本质是一个Handler类。
然后我们来简单介绍一下该类提供的几个重要方法:
- //将当前网络注册到ConnectivityService
- public void register() { }
- //处理网络请求,用于打开或者释放当前连接
- private void handleAddRequest(NetworkRequest request, int score) {}
- //更新当前网络的分值
- public void setScoreFilter(int score) {}
//将当前网络注册到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 void startNetwork() { }
protected void stopNetwork() { }
protected void needNetworkFor(NetworkRequest networkRequest, int score) { }
protected void releaseNetworkFor(NetworkRequest networkRequest) { }
这些方法都是protected属性,他们的作用就是在评分后,决定当前网络被激活或者释放,因此
一般都会在子类中被覆盖。
属性和方法介绍到这里,下面介绍该对象的使用。
二、NetworkFactory在数据连接中的初始化过程
简单介绍一下DcTracker,他是数据网络的提供者,承担着APN参数选择、数据业务建立与释放等作用。
在DcTracker初始化时将会初始化数据的NetworkFactory对象:
- @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.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();
- }
- }
@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只需要三个步骤:
1、初始化NetworkFactory子类,并实现其中的protected方法,他们的作用就是在网络评分时决定激活或者释放当前的网络连接。
2、设置当前网络的分值
3、将当前NetworkFactory注册到ConnectivityService
三、NetworkFactory在WIFI连接中的初始化过程
同样的,在WIFI检测到系统初始化完毕的时候,将会创建自己的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;
- }
- }
@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() {
- }
- }
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来释放)。
四、NetworkFactory的注册过程
虽然注册的过程是向ConnectivityManager申请的,但是从前一节《 Framework中的连接管理机制》中我们知道,ConnectivityManager将会把相应请求交给ConnectivityService来处理,对于注册的申请,也是传递到ConnectivityService中的registerNetworkFactory()来处理的:
- @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.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 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);
- }
private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
mNetworkFactoryInfos.put(nfi.messenger, nfi);
nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
}
到这里我们发现,
ConnectivityService将当前的NetworkFactoryInfo保存到mNetworkFactoryInfos中,然后向当前的NetworkFactory发起AsyncChannel
单向通道申请(
AsyncChannel相关介绍见这里)。
申请成功时,将会向当前的mTrackerHandler发送CMD_CHANNEL_HALF_CONNECTED消息:
- @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;
- }
- }
- }
- }
@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)) {
- }
- }
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收到该请求时的处理:
- @NetworkFactory.java
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case CMD_REQUEST_NETWORK: {
- handleAddRequest((NetworkRequest)msg.obj, msg.arg1);
- break;
- }
- }
- }
@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);
- }
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;
- }
- }
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。
当NetworkRequestInfo被requested过(也就是当前网络被needNetworkFor过),此时如果再次收到请求,并且携带的新score大于当前NetworkFactory所处网络的mScore,那么就说明当前NetworkFactory所在网络优先级已经不是最高,需要将其releaseNetworkFor掉,并标记NetworkRequestInfo.requested=false。
对于初始化流程来说,由于NetworkRequestInfo是刚才在handleAddRequest新创建的,所以其requested状态必然为false,而且我们前面提到,ConnectivityService发送CMD_REQUEST_NETWORK时携带的分值参数为0,并且对于数据网络来说,其mScore=50,因此此时的判定状态将会是:n.requested=false AND n.score < mScore。
也就是说,对于数据网络环境初始化过程来说,将会满足第一个if判断,进入needNetworkFor流程,也就是触发数据网络的建立。
至此,NetworkFactory注册流程结束。