我正在開發一個Android應用程序,它定期通過REST API調用回報數據服務器。每當應用程序嘗試發送其中一個報告時,但沒有網絡頻道(wifi或移動數據)可用時,應用程序將爲該任務創建一個包裝並將其放入與BroadcastReceiver
相關的隊列中。接收者收聽android.net.wifi.STATE_CHANGE
或android.net.conn.CONNECTIVITY_CHANGE
,然後嘗試在新連接上執行入隊任務。所有的認證邏輯也在這裏處理。實際的請求POST將通過Retrofit庫發送出去。(Android)有沒有可靠的信號來表明網絡通道是可路由的?
我的問題是,每當網絡訪問「回來」,並且接收器試圖啓動所有正在等待的任務時,我總是會回到java.net.UnknownHostException
,指出數據服務器的主機名沒有關聯地址。看起來,雖然Android設備知道它已經連接到網絡,但它仍然不知道從哪裏獲取DNS,並且在此狀態下出現的任何請求都會失敗。
D/Retrofit﹕ java.net.UnknownHostException: Unable to resolve host "[REDACTED]": No address associated with hostname
at java.net.InetAddress.lookupHostByName(InetAddress.java:424)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at com.squareup.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.squareup.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:266)
at com.squareup.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:240)
at com.squareup.okhttp.internal.http.RouteSelector.nextUnconnected(RouteSelector.java:156)
at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:130)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:312)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:235)
at com.squareup.okhttp.Call.getResponse(Call.java:262)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:219)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192)
at com.squareup.okhttp.Call.execute(Call.java:79)
at retrofit.client.OkClient.execute(OkClient.java:53)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at [REDACTED](Native Method)
at [REDACTED]
[etc]
Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname)
Caused by: libcore.io.ErrnoException: getaddrinfo failed: ENETUNREACH (Network is unreachable)
的根本原因異常(libcore.io.ErrnoException
)聲稱,網絡不可達,但我甚至不嘗試,直到我已經後從Android OS接收的意圖這個執行特別是因爲的實際上,網絡現在是可達的。
我驗證無線網絡的可用性代碼:
protected static boolean isWifiAvailable(WifiManager wifi)
{
WifiInfo info = wifi.getConnectionInfo() ;
if(info == null) return false ;
if(info.getNetworkId() == -1) return false ;
if(info.getSupplicantState() != SupplicantState.COMPLETED)
return false ;
return true ;
}
我覈實移動數據可用性代碼:
protected static boolean isMobileDataAvailable(TelephonyManager tmgr)
{
return(tmgr.getDataState() == TelephonyManager.DATA_CONNECTED) ;
}
問:有沒有更可靠的信號 - 這是我沒有檢查在WifiInfo
和TelephonyManager
- 那就表示網絡頻道真的是,真的準備好了嗎?或者這是一個沒有明確決議的競賽條件?
這是一個神測試,但它不是確鑿的。 – EJP