首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android Service 中網絡請求 Connection Refused 問題排查

     編輯:程式設計疑難解答

錯誤現象

Service 中的線程發起 HTTP 請求,首次啟動正常,但 Service 重啟或長時間運行後報 ECONNREFUSED,點擊主頁面後恢復。

可能原因

  1. 服務端未就緒:Service 啟動時服務器端口未監聽,導致連接被拒。
  2. 網絡狀態變化:Wi-Fi 休眠、IP 變更導致舊 Socket 失效。
  3. 線程與 Service 生命周期不匹配:Service 被殺後線程仍持有舊連接對象。
  4. 並發衝突:多線程共用單例 HttpURLConnection 或未正確關閉流。

解決方案

  • 加入重試機制:指數退避重試,捕獲 ConnectException 後延遲重連。
  • 監聽網絡變化:註冊 ConnectivityManager 廣播,網絡恢復時重新建立連接。
  • 使用 OkHttp/Retrofit:替換原始 HttpURLConnection,自動處理連接池、重試、超時。
  • 前台 Service:startForeground() 降低被殺概率,並在 onStartCommand 返回 START_STICKY。

代碼改進示例(OkHttp)

OkHttpClient client = new OkHttpClient.Builder()
    .retryOnConnectionFailure(true)
    .connectTimeout(10, TimeUnit.SECONDS)
    .build();

Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
    @Override public void onFailure(Call call, IOException e) {
        // 記錄日誌,安排重試
    }
    @Override public void onResponse(Call call, Response response) {
        // 處理響應
    }
});

總結

避免在 Service 線程中直接使用底層 HTTP API,採用成熟網絡庫並配合生命周期管理,可顯著提升穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved