2017-09-11 69 views
0

当提供互联网连接时,我的应用程序可以使用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()。有没有其他办法来处理这种情况?

+0

你为什么不尝试使用Retrofit2代替OkHttp?通常,Retrofit适用于Android,OkHttp适用于“标准Java”。 –

+0

UnknownHostException永远不会抛出onFailure()方法。 – canihazurcode

回答

-1

的UnknownHostException是IOException子类,所以你可以捕捉IOException异常,这将修复它为您

+0

我尝试过围绕代码负责连接尝试{...} catch(Exception e){...},但它不会抛出任何异常 – canihazurcode

+0

catch(IOException e) –

+1

IOException是一个子类的例外。 – canihazurcode

1

我使用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; 
      } 
     } 
    } 
相关问题