当我有文件传输并且设备丢失互联网连接时
DataOutputStream.write
有时几乎无法阻挡。
我知道这是正常的,因为底层套接字层正在尽可能快地完成它的工作。
我正在考虑使用
registerReceiver(mConnRec,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
并在发生这种情况时抓住并执行socket.close()
或DataOutputStream.close()
强制DataOutputStream.write
停止阻止并发生正常的代码流
更快。
这会起作用吗或我该如何控制阻止?
我的另一个想法是开始一个每5秒工作一次的线程 测试互联网就像这样存在
public boolean haveNetworkConn(Context ctx)
{
boolean HaveConnectedWifi = false;
boolean HaveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo)
{
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
HaveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
HaveConnectedMobile = true;
}
return HaveConnectedWifi || HaveConnectedMobile;
}
如果返回false,我可以强制执行socket.close。
真的想对这个想法有一些反馈
更新
使用registerReceiver BroadcastReceiver运行一些测试
当我关闭OutputStream和套接字本身的数据时没有任何反应。
它在out.write(buffer, 0, val);
处继续阻止。这是最意想不到的
使用Eclipse并放置断点和步进..
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)){
return;
}
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
NetworkInfo aNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (!noConnectivity)
{
if ((aNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) || (aNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI))
{
//Handle connected case
}
}
else
{
if ((aNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) || (aNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI))
{
//Handle disconnected case
if(socket != null)
try {
out.close();
in.close();
socket.close();
} catch (IOException e) {
}
}
}
}
};
答案 0 :(得分:2)
是的,关闭套接字是一种解除当前在套接字上阻止的方法调用的方法。引自the documentation for close()
:
此套接字上的I / O操作中当前阻塞的任何线程都将 抛出一个SocketException。
另请参阅“实践中的Java并发”一节中的第7.1.6节。
为CONNECTIVITY_ACTION
注册接收器是一个比每5秒轮询一次更好的解决方案,因为它可以节省CPU周期,并可能在应用程序对连接变化的反应中提供更好的延迟。