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

Android 開機自啟 Service 無法發送 HTTP 請求:網絡未就緒導致 UnknownHostException 解決

     編輯:程式設計疑難解答

現象描述

App 啟動 Service 定時發送 HTTP POST,手動啟動正常(返回 200),但配置 BOOT_COMPLETED 廣播自啟後,請求拋 Unable to resolve host "...": No address associated with hostname,僅網絡請求失敗,其他功能正常。

根本原因

開機廣播觸發時,系統網絡服務尚未完全就緒(Wi-Fi/移動數據未連接、DNS 未就緒)。Service 啟動即發起請求,DNS 解析失敗,拋 UnknownHostException。

解決方案(按推薦度排序)

  1. 輪詢等待網絡就緒:
    
    private void waitForNetwork() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        int retry = 0;
        while (retry++ < 30) { // 最多等 30s
            NetworkInfo active = cm.getActiveNetworkInfo();
            if (active != null && active.isConnected()) {
                // 額外驗證 DNS
                try { InetAddress.getByName("www.google.com"); break; }
                catch (Exception ignored) {}
            }
            SystemClock.sleep(1000);
        }
    }
    
    在 onCreate() 或首次請求前調用。
  2. 使用 WorkManager / JobScheduler:設置 setRequiredNetworkType(NetworkType.CONNECTED),系統自動在網絡就緒時觸發任務,**無需手動輪詢**,且符合 Doze/App Standby 省電策略(API 21+ 推薦)。
  3. 監聽網絡變化廣播:註冊 CONNECTIVITY_ACTION(API 24+ 需動態註冊),收到連接廣播後再啟動定時任務。
  4. 延遲啟動:SystemClock.sleep(10000) 粗暴延遲,**不推薦**(機型差異大,不可靠)。

最佳實踐總結

  • **放棄 BOOT_COMPLETED + Service 定時輪詢模式**,改用 **WorkManager (PeriodicWorkRequest)**,聲明網絡約束,系統保證網絡就緒才執行,代碼更簡潔、功耗更低、兼容性更強。
  • 若必須用 Service,務必在請求前**主動檢測網絡連通性 + DNS 解析**,失敗則指數退避重試。

核心教訓:**開機即聯網 = 網絡未就緒**,主動等待或交給系統調度器是正解。

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