2017-09-11 98 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; 
      } 
     } 
    } 
相關問題