数据业务中的短连接,是一种为了满足业务需求,临时建立起来的连接。当业务完成通信需求后,这种数据连接会被框架释放掉。与之相对,长连接一旦拨号成功就会一直存在下去,除非用户主动关闭或者终端受到网络等因素的影响导致连接不可用。
一种比较常见的例子,就是发送彩信时,终端将建立短连接;当彩信发送结束时,短连接将被释放掉。
在这篇博客中,我们就从彩信入手,看看Android中是如何建立和释放短连接的。
1 MmsService
Android中彩信相关的应用为MmsService,我们看看它AndroidManifest.xml中的部分片段:
<application android:label="MmsService"
android:process="com.android.phone"
android:usesCleartextTraffic="true">
<service android:name=".MmsService"
android:enabled="true"
android:exported="true"/>
</application>
容易看出MmsService是运行在Phone进程中的。在这篇博客中,我们不深入研究彩信服务的启动和收发彩信的过程,主要看看彩信如何建立和释放短连接。
在MmsService.java中,每一次发送彩信均会形成一个MmsRequest(抽象类,实现类为SendRequest和DownloadRequest),并将其加入到运行队列中:
private void addToRunningRequestQueueSynchronized(final MmsRequest request) {
...........
final int queue = request.getQueueType();
//判读queue值的有效性
............
mRunningRequestCount++;
mCurrentSubId = request.getSubId();
mRunningRequestExecutors[queue].execute(new Runnable() {
@Override
public void run() {
try {
//MmsRequest执行
request.execute(MmsService.this, getNetworkManager(request.getSubId()));
} finally {
synchronized (MmsService.this) {
mRunningRequestCount--;
if (mRunningRequestCount <= 0) {
//将位于pending队列中的请求,加入到running队列中
movePendingSimRequestsToRunningSynchronized();
}
}
}
}
}
}
在上面对代码中,利用getNetworkManager创建了MmsRequest专属的MmsNetworkManger:
//subId对应于发送彩信的卡
private MmsNetworkManager getNetworkManager(int subId) {
synchronized (mNetworkManagerCache) {
MmsNetworkManager manager = mNetworkManagerCache.get(subId);
if (manager == null) {
manager = new MmsNetworkManager(this, subId);
mNetworkManagerCache.put(subId, manager);
}
return manager;
}
}
先看看MmsNetworkManager的构造函数:
public MmsNetworkManager(Context context, int subId) {
............
//构造出申请网络的request
//注意Capability指定为MMS,同时NetworkSpecifier指定为对应的sub id
mNetworkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
.setNetworkSpecifier(Integer.toString(mSubId))
.build();
}
接下来,看看MmsRequest的execute方法:
public void execute(Context context, MmsNetworkManager networkManager) {
..........
//检查是否做好准备工作
if (!ensureMmsConfigLoaded()) {
........
} else if (!prepareForHttpRequest()){
........
} else {
long retryDelaySecs = 2;
for (int i = 0; i < RETRY_TIMES; i++) {
try {
//利用MmsNetworkManager建立短连接
networkManager.acquireNetwork(requestId);
try {
//进行实际的发送或接收
............
} finally {
//利用MmsNetworkManager释放段连接
networkManager.releaseNetwork(requestId);
}
} .........//进行捕获异常等操作
}
//处理发送结果
processResult(co