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

Android 應用退出前發送網絡請求的正確姿勢

     編輯:程式設計綜合問答

核心結論

無法保證在進程被系統殺死(用戶滑動關閉、內存不足回收)後仍能發送請求。 Android 系統不允許應用在進程銷毀後繼續執行代碼(無法常駐內存)。

可行方案:正常退出流程中同步/異步發送

場景:用戶點擊「退出登錄」/「退出應用」按鈕

// Activity/Fragment 中
private void exitApp() {
    // 1. 顯示加載狀態
    showLoading("正在退出...");

    // 2. 發送退出請求(同步或異步均可,視業務)
    ApiService.logout(new Callback() {
        @Override
        public void onSuccess(Response resp) {
            // 3. 請求成功/失敗後,真正結束進程
            finishAffinity(); // 關閉所有 Activity
            System.exit(0);   // 確保進程退出
        }

        @Override
        public void onFailure(Throwable t) {
            // 即使失敗也要退出,避免卡死
            finishAffinity();
            System.exit(0);
        }
    });
}

為什麼 onDestroy / onStop 不可靠?

生命周期觸發時機能否發送網絡請求
onPauseActivity 失去焦點可,但用戶可能只是切換應用
onStopActivity 完全不可見可,但同樣非真正退出
onDestroyActivity 銷毀(配置變更、finish、系統回收)不可靠:系統回收進程時不調用,或執行時間極短(<5ms)會被殺死

進階:WorkManager 保證最終送達(延遲執行)

若業務允許「延遲幾分鐘送達」,可使用 `WorkManager` 排期一次性任務:

OneTimeWorkRequest logoutWork = new OneTimeWorkRequest.Builder(LogoutWorker.class)
        .setInitialDelay(1, TimeUnit.MINUTES) // 給系統喘息時間
        .build();
WorkManager.getInstance(context).enqueue(logoutWork);

// LogoutWorker.doWork() 中發送請求,返回 Result.success()

優點:即使進程被殺,系統會在適當時機重啟進程執行 Worker。
缺點:非實時、需處理重複執行冪等性。

不可行方案澄清

  • ❌ `Service` + `START_STICKY`:系統內存緊張仍會殺死,且 Android 8+ 後台執行限制極嚴。
  • ❌ `Foreground Service`:需持續顯示通知,用戶體驗極差,不適合「退出」場景。
  • ❌ `AlarmManager` / `BroadcastReceiver`:同樣受 Doze/Standby 限制,無法保證即時。

總結

  1. 僅在用戶主動點擊退出的正常流程中,發送請求並等待響應後 `finishAffinity()`。
  2. 異常進程死亡(滑動關閉、系統回收)**無法攔截、無法發送請求**,服務端需通過心跳超時 / Token 過期 / 設備唯一標識實現會話清理。
  3. 若有「離線操作同步」需求,採用「本地緩存 + 啟動時同步」架構,而非依賴退出瞬間上傳。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved