我目前正在构建一个通过 WebSocket (通过来自 TooTallNate 的 Java WebSockets)连接到服务器的 Android 应用程序。问题是在我的 Moto Z Play(Android 8.0)和我的 Acer Iconia A3-A40(Android 6.0)上,WebSocket 得到在随机时间(8 到 25 分钟之间)后关闭。在我的 HTC ONE(Android 5.0)上,我添加了唤醒锁和 wifilock(让它运行 3 小时,完美运行)后,这并没有发生。Android Studio Emulator 上不会出现此问题。在我的 Moto Z Play 上,在我的 WebSocket 关闭之前,我得到了以下日志:
> 12-14 19:16:23.409 1443-2088/? I/chatty: uid=1000(system) IpManager.wlan0 expire 1 line
12-14 19:16:23.411 946-1266/? D/CommandListener: Setting iface cfg
12-14 19:16:23.412 1443-16705/? I/chatty: uid=1000 system_server expire 1 line
12-14 19:16:23.412 1443-16703/? I/chatty: uid=1000 system_server expire 1 line
12-14 19:16:23.461 2125-2125/? E/wpa_supplicant: disconnect rssi= -68
12-14 19:16:23.462 2125-2125/? I/wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid=f5:eb:3d:bf:de:b6 reason=3 locally_generated=1 disconnect_rssi=68
12-14 19:16:23.464 2125-2125/? E/wpa_supplicant: nl80211: Failed to open /proc/sys/net/ipv4/conf/wlan0/drop_unicast_in_l2_multicast: No such file or directory
nl80211: Failed to set IPv4 unicast in multicast filter
12-14 19:16:23.474 946-1257/? I/Netd: Destroyed 1 sockets on <the ipadress of the smartphone> in 1.0 ms
12-14 19:16:23.479 2125-2125/? E/wpa_supplicant: eap_proxy: eap_proxy_notify_config
nl80211: Failed to open /proc/sys/net/ipv4/conf/wlan0/drop_unicast_in_l2_multicast: No such file or directory
12-14 19:16:23.479 20544-20708 D/SocketSerivce: onClose (Here the WebSocket is closed)
12-14 19:16:23.479 2125-2125/? E/wpa_supplicant: nl80211: Failed to set IPv4 unicast in multicast filter
12-14 19:16:23.493 2125-2125/? E/wpa_supplicant: eap_proxy: eap_proxy_notify_config
eap_proxy: eap_proxy_notify_config
我做了一些研究,并认为暂停网络访问会是一个打瞌睡的问题,但有一些事情反对这一点:
- websocket 在 ForegroundService 中启动(不包括打瞌睡?)
- 设备已插入(插入时打盹不会启动)并且 websocket 仍然停止
- 即使更改电池优化,它仍然发生(一段时间后但仍然发生)
(但我可能是错的)
到目前为止我做了什么:
通过以下方式启动 ForegroundService:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
}else{
startService(intent);
}
获取 wakeLock 和 wifilock(并在 websocket 关闭时释放):
powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLockMyApp");
wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "WifiLockMyApp");
wakeLock.acquire();
wifiLock.acquire();
检查了 onStartCommand-Method
startForeground(..)
return START_STICKY;
提前致谢