Java 在Android上通过OkHttp连接到websocket时,如何捕获未知隐藏异常?
当提供internet连接时,我的应用程序可以使用OkHttp(V3.9.0)通过websocket连接到服务器。我想优雅地处理连接到websocket的失败尝试(即,当没有可用的internet连接时) 我使用以下代码建立与服务器的连接:Java 在Android上通过OkHttp连接到websocket时,如何捕获未知隐藏异常?,java,android,exception,websocket,okhttp,Java,Android,Exception,Websocket,Okhttp,当提供internet连接时,我的应用程序可以使用OkHttp(V3.9.0)通过websocket连接到服务器。我想优雅地处理连接到websocket的失败尝试(即,当没有可用的internet连接时) 我使用以下代码建立与服务器的连接: Request request = new Request.Builder() .url(BuildConfig.WS_URL) .build(); client.newWebSocket(request, webSocke
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方法。然而,未知的后异常仍然是未知的。是否有任何方法可以捕获此异常?我不想使用
Thread.setDefaultUncaughtExceptionHandler()
。是否有其他方法来处理这种情况?未知HostException是的子类,因此您可以捕获IOException,这将为您修复它大约一个月前,我尝试使用Android的OkHttp与WebSockets服务器通信,但它不想工作。因此,我使用了一种低级的通信方式,它就像一种魅力,只使用基本的Java
下面是代码的外观(在我的例子中,用于向服务器发送信息):
使用这种低级方法,我能够绕过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;
}
}
}
private void connectToWifi(){
字符串networkSSID=“YourWiFiSSID”;
WifiConfiguration wifiConfig=新的WifiConfiguration();
wifiConfig.SSID=“\”+网络SSID+“\”;
wifiConfig.allowedKeyManagement.set(wifiConfig.keymanagement.NONE);
WifiManager WifiManager=(WifiManager)getApplicationContext().getSystemService(Context.WIFI_服务);
wifiManager.addNetwork(wifiConfig);
//如果已禁用WiFi,请启用WiFi
如果(!wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(true);
}
//获取Wi-Fi配置列表
List-wifiConfigurationList=wifiManager.getConfiguredNetworks();
用于(无线配置配置:无线配置列表){
//如果配置正确,请连接到它
如果(configuration.SSID!=null&&configuration.SSID.equals(“\”+networkSSID+“\”)){
wifiManager.disconnect();
wifiManager.enableNetwork(configuration.networkId,true);
//wifiManager.reconnect();
打破
}
}
}
为什么不尝试使用Reformation2而不是OkHttp?通常,改型适用于Android,OkHttp用于“标准Java”。onFailure()方法中从不抛出UnknownHostException。我尝试过使用try{…}catch(Exception e){…}围绕负责连接的代码块,但它不会抛出任何exceptioncatch(IOException e)IOException是Exception的子类。每个异常都是Exception类的子类,请尝试一下;)Throwable类是Java语言中所有错误和异常的超类。Java虚拟机只能抛出作为此类(或其子类之一)实例的对象,或者可以通过Java throw语句抛出这些对象。类似地,只有这个类或它的一个子类可以是catch子句中的参数类型。如果这个没有捕捉到,那么什么都不会,这意味着你在其他地方有错误。
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;
}
}
}