預設 HttpClient 無超時限制,伺服器無回應時請求會無限阻塞,導致 ANR 或使用者體驗極差。必須明確設定**連線超時**與 **Socket 讀取超時**。
核心程式碼 (Apache HttpClient / DefaultHttpClient)
HttpGet httpGet = new HttpGet(url);
HttpParams httpParams = new BasicHttpParams();
// 1. 連線超時:建立 TCP 連線的最長等待時間 (毫秒)
int connectionTimeout = 3000; // 3 秒
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeout);
// 2. Socket 讀取超時:等待資料傳輸的最長間隔 (毫秒)
int socketTimeout = 5000; // 5 秒
HttpConnectionParams.setSoTimeout(httpParams, socketTimeout);
// 3. 套用參數建立 Client
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
// 4. 執行請求
HttpResponse response = httpClient.execute(httpGet);
超時類型差異對照
| 超時類型 | 觸發情境 | 拋出異常 | 建議值 |
| Connection Timeout | TCP 三次交握失敗、伺服器 IP 不通、防火牆阻擋 | java.net.SocketTimeoutException: Socket is not connected 或 ConnectException | 3-10 秒 |
| Socket Timeout (SoTimeout) | 連線建立後,伺服器超過指定時間未傳回任何資料 | java.net.SocketTimeoutException: The operation timed out | 5-30 秒 (視檔案大小、API 複雜度) |
現有 HttpClient 套用參數
若已有 DefaultHttpClient 或 AndroidHttpClient 實例:
httpClient.setParams(httpParams);
現代替代:OkHttp / Retrofit (強烈推薦)
Apache HttpClient 於 Android 6.0 移除,Android 9.0 完全不可用。新專案請直接使用 OkHttp 或 Retrofit:
OkHttp 設定超時
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.SECONDS) // 連線超時
.readTimeout(10, TimeUnit.SECONDS) // 讀取超時
.writeTimeout(10, TimeUnit.SECONDS) // 寫入超時
.callTimeout(30, TimeUnit.SECONDS) // 整體呼叫超時 (OkHttp 4.9+)
.build();
Request request = new Request.Builder().url(url).build();
try (Response response = client.newCall(request).execute()) {
// 處理回應
}
Retrofit 設定超時
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(3, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
最佳實務清單
- ✅ 所有網路請求**必須**設定超時
- ✅ 區分連線超時與讀取超時,依業務調整
- ✅ 使用 OkHttp/Retrofit 取代舊 HttpClient
- ✅ 實作重試機制(指數退避)處理暫時性超時
- ✅ 監控超時率,作為效能優化依據
正確設定超時,是打造穩健網路層的第一步。
- 上一篇文章: Android 透明 Activity 實作:主題樣式設定與應用場景
- 下一篇文章: Android 網路連線檢查:ConnectivityManager 正確用法與 InetAddress 陷阱
Copyright ©
程式碼之家 All Rights Reserved