如何在Android上通过OkHttp连接到websocket时捕获UnknownHostException?
当提供互联网连接时,我的应用程序可以使用OkHttp(v 3.9.0)通过websocket连接到服务器。我想要处理失败的尝试,以优雅地连接到websocket(即没有互联网连接可用时)。如何在Android上通过OkHttp连接到websocket时捕获UnknownHostException?
我建立使用下面给出的代码到我的服务器的连接:
Request request = new Request.Builder()
.url(BuildConfig.WS_URL)
.build();
client.newWebSocket(request, webSocketListener);
我的侦听器处理故障和日志的UnknownHostException。
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
if(t instanceof UnknownHostException) {
Log.v("LISTENER", "UNKNOWN HOST EXCEPTION");
}
}
结果是
09-11 15:16:32.773 18384-18473/com.example.app V/LISTENER: UNKNOWN HOST EXCEPTION
09-11 15:16:32.775 18384-18473/com.example.app E/AndroidRuntime: FATAL EXCEPTION: OkHttp https://my.server.url/...
Process: com.example.app, PID: 18384
和应用程序崩溃。
我试着用try-catch包围第一块代码,捕获抛出的任何异常,但后来我发现UnknownHostException必须已经由OkHttpClient内部处理过了。 OkHttpClient然后调用我的侦听器的onFailure方法。但是,UnknownHostException仍然未被捕获。有什么办法来捕捉这个异常?我不想用Thread.setDefaultUncaughtExceptionHandler()
。有没有其他办法来处理这种情况?
的UnknownHostException是IOException子类,所以你可以捕捉IOException异常,这将修复它为您
我尝试过围绕代码负责连接尝试{...} catch(Exception e){...},但它不会抛出任何异常 – canihazurcode
catch(IOException e) –
IOException是一个子类的例外。 – canihazurcode
我使用OkHttp从Android的一个月与WebSockets的服务器通信多年前尝试过了,它没”不想工作。因此,我使用了一种低级别的沟通方式,它的功能就像一个魅力,只有基本的Java。
下面的代码的外观(用于将信息发送到服务器,在我的情况):
//this is the method that sends the String passed as the parameter to the Sockets server
private void sendMessage(final String stringToSend) throws IOException {
if(isOnline()){
new Thread(new Runnable() {
@Override
public void run() {
Socket socket = null;
try {
socket = new Socket("192.168.0.1",1001);
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream DOS = null;
try {
DOS = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
DOS.writeUTF(stringToSend);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
使用这种低级的做法,我可以用OkHttp绕过,并与刚刚标准做了我的工作Java的。现在,我知道你想从服务器获取数据,而不是发布它,就像我的情况一样,但是也许它只是给你一个关于Java的解决方法的想法。
此外,你可能会像我一样写一个isOnline()
方法。只有在线时才会尝试与服务器通信。也许这样,你会解决你的问题并保留你当前的代码。这里是我的isOnline()
方法:
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
//if you're not connected through Wi-Fi...
if(netInfo.getType() != ConnectivityManager.TYPE_WIFI){
Toast.makeText(this,"This app doesn't work without Wi-Fi",Toast.LENGTH_LONG).show();
return false;
}
return true;
} else {
return false;
}
}
你甚至可以使应用程序试图连接到一定的Wi-Fi使用此:
private void connectToWifi() {
String networkSSID = "YourWiFiSSID";
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + networkSSID + "\"";
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiManager.addNetwork(wifiConfig);
//enable the WiFi if it's disabled
if (!wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(true);
}
//get the list of Wi-Fi configurations
List<WifiConfiguration> wifiConfigurationList = wifiManager.getConfiguredNetworks();
for(WifiConfiguration configuration : wifiConfigurationList){
//if the configuration is the right one, connect to it
if(configuration.SSID != null && configuration.SSID.equals("\"" + networkSSID + "\"")){
wifiManager.disconnect();
wifiManager.enableNetwork(configuration.networkId,true);
// wifiManager.reconnect();
break;
}
}
}
你为什么不尝试使用Retrofit2代替OkHttp?通常,Retrofit适用于Android,OkHttp适用于“标准Java”。 –
UnknownHostException永远不会抛出onFailure()方法。 – canihazurcode