Open krishnamn opened 8 years ago
Hi i Solved my issue by adding couple of conditions in connect sdk code.....Thanks
I'm having the same problem. Can you please share what the solution was?
@krishnamn could you share your solution?
@krishnamn Could you please share your solution?
Did some more in-depth investigation on this and it seems Android Nougat (7) uses openJDK as runtime (effectively ditching the "standard" runtime implementation with the OpenJDK one). If you check the source for DatagramSocket.java in android-24 sources packet it differs from android-22 for example. So then the disconnect method are different:
The before:
/**
* Disconnects this UDP datagram socket from the remote host. This method
* called on an unconnected socket does nothing.
*/
public void disconnect() {
if (isClosed() || !isConnected()) {
return;
}
impl.disconnect();
address = null;
port = -1;
isConnected = false;
}
The after:
/**
* Disconnects the socket. If the socket is closed or not connected,
* then this method has no effect.
*
* @see #connect
*/
public void disconnect() {
synchronized (this) {
if (isClosed())
return;
if (connectState == ST_CONNECTED) {
impl.disconnect ();
}
connectedAddress = null;
connectedPort = -1;
connectState = ST_NOT_CONNECTED;
}
}
Nothing wrong with this, until you look closer into the receive
method:
public synchronized void receive(DatagramPacket p) throws IOException {
synchronized (p) {
if (!isBound())
bind(new InetSocketAddress(0));
// ----- BEGIN android -----
if (pendingConnectException != null) {
throw new SocketException("Pending connect failure", pendingConnectException);
}
// ----- END android -----
if (connectState == ST_NOT_CONNECTED) {
...
Well now we can see the issue: the disconnect
method in android-24 sources actually tries to obtain a lock for the current DatagramSocket object (this
) which unfortunately is locked in the receive
method (if the socket is connected).
What this is, is a deadlock.
What @krishnamn probably did was to check if the socket is connected, and if so, close the socket, not disconnect it, in SSDPClient.java (connect-sdk):
So this:
/** Close the socket */
public void close() {
if (multicastSocket != null) {
try {
multicastSocket.leaveGroup(multicastGroup, networkInterface);
} catch (IOException e) {
e.printStackTrace();
}
multicastSocket.close();
}
if (datagramSocket != null) {
datagramSocket.disconnect();
datagramSocket.close();
}
}
Becomes this:
/** Close the socket */
public void close() {
if (multicastSocket != null) {
try {
multicastSocket.leaveGroup(multicastGroup, networkInterface);
} catch (IOException e) {
e.printStackTrace();
}
multicastSocket.close();
}
if (datagramSocket != null) {
if (!datagramSocket.isClosed(){
datagramSocket.close();
}
datagramSocket.disconnect();
datagramSocket.close();
}
}
Also, FYI there are some issues with hashCode() for Enums in the OpenJDK implementation, if anyone encounters strange behavior in their apps.
Sorry for the late reply...In my case it got solved by handling the below cases in Connect SDk -- > SSDPClient class --> Close method
if(this.datagramSocket != null) {
if(this.datagramSocket.isConnected()) {
this.datagramSocket.disconnect();
}
if(!this.datagramSocket.isClosed()) {
this.datagramSocket.close();
}
Hello, I tried the solutions mentioned above, but I still could not solve the problem. Can you help me?
I am getting this same issue. Is there any other solution for app freeze?
help I have same issue
Hi Application got freezed (ANR state) when the network got disconnected after opening the app in Nexus 9 (Android 7.0 ) . It was observed in the trace logs that a dead lock occured on com.connectsdk.discovery.provider.ssdp.SSDPClient.close . Below is the partial trace lock. Please check
`"main" prio=5 tid=1 Blocked | group="main" sCount=1 dsCount=0 obj=0x73799530 self=0xe5b04400 | sysTid=2217 nice=-4 cgrp=default sched=0/0 handle=0xe878e534 | state=S schedstat=( 3867775484 1969408624 9506 ) utm=305 stm=80 core=0 HZ=100 | stack=0xff378000-0xff37a000 stackSize=8MB | held mutexes= at java.net.DatagramSocket.disconnect(DatagramSocket.java:506)
waiting to lock <0x01d93268> (a java.net.DatagramSocket) held by thread 68 at com.connectsdk.discovery.provider.ssdp.SSDPClient.close(SSDPClient.java:135) at com.connectsdk.discovery.provider.SSDPDiscoveryProvider.stop(SSDPDiscoveryProvider.java:177) at com.connectsdk.discovery.provider.SSDPDiscoveryProvider.reset(SSDPDiscoveryProvider.java:190) at com.connectsdk.discovery.DiscoveryManager$1.onReceive(DiscoveryManager.java:237) at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1122) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke!(Native method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Thread-18" prio=5 tid=68 Native | group="main" sCount=1 dsCount=0 obj=0x12d5e0d0 self=0xcacefa00 | sysTid=2339 nice=0 cgrp=default sched=0/0 handle=0xbdcff920 | state=S schedstat=( 29062667 12680420 32 ) utm=1 stm=0 core=1 HZ=100 | stack=0xbdbfd000-0xbdbff000 stackSize=1038KB | held mutexes= kernel: switch_to+0x74/0x8c kernel: skb_recv_datagram+0x328/0x360 kernel: udpv6_recvmsg+0xb8/0x700 kernel: inet_recvmsg+0x38/0x50 kernel: sock_recvmsg+0xd0/0xf4 kernel: SyS_recvfrom+0xdc/0x26c kernel: compat_sys_recvfrom+0x10/0x18 kernel: ret_fast_syscall+0x0/0x24 native: #00 pc 00049854 /system/lib/libc.so (recvfrom+16) native: #01 pc 0004fbb5 /system/lib/libc.so (recvfrom_chk+20) native: #02 pc 0000e30f /system/lib/libopenjdk.so (NET_RecvFrom+70) native: #03 pc 0001a4ab /system/lib/libopenjdk.so (PlainDatagramSocketImpl_receive0+294) native: #04 pc 000b56d9 /system/framework/arm/boot.oat (Java_java_net_PlainDatagramSocketImpl_receive0Ljava_net_DatagramPacket_2+108) at java.net.PlainDatagramSocketImpl.receive0(Native method)