When i have a file transfer and the device loses internet connection
the DataOutputStream.write is sometimes blocking almost indefinably.
i know this is kind of normal since the underlying socket layers are doing it’s job as fast as it can.
I was thinking to use the
registerReceiver(mConnRec,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
and catch when this happen and do a socket.close() or DataOutputStream.close()
to force the DataOutputStream.write to stop block and normal code flow would occur
faster.
Will this work or what can i do to control the blocking?
Another ide i had was to start a thread which job is to every 5 sec
test internet exist like this
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;
}
If that return false i could force a socket.close maybe.
Would really like to have some feedback on this ideas
UPDATE
Running some tests using the registerReceiver BroadcastReceiver.
Nothing happens when i close the data in and OutputStream and the socket itself.
It keeps on blocking at out.write(buffer, 0, val);. This was most unexpected.
using Eclipse and placing breakpoints and stepping..
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) {
}
}
}
}
};
Yes, closing a socket is a way to unblock all the method calls currently blocked on the socket. Quoting from the documentation for
close():See also section 7.1.6 in “Java Concurrency in Practice”.
Registering a receiver for
CONNECTIVITY_ACTIONis a better solution than polling every 5 seconds since it saves CPU cycles and potentially allows for better latency in your application’s reaction to connectivity change.