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

Android 廣播註冊重複導致應用崩潰的解決方案

     編輯:程式設計疑難解答

問題場景

開發 WiFi 相關應用時,在 onCreate() 和 onResume() 中重複註冊廣播接收器。當用戶通過狀態欄關閉 WiFi 後返回應用,應用發生崩潰,懷疑是廣播重複發送/註冊導致。

錯誤代碼模式

// 錯誤示範:重複註冊
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    registerReceiver(wifiReceiver, filter);  // 第一次註冊
}

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(wifiReceiver, filter);  // 第二次註冊!會拋出 IllegalArgumentException
}

解決方案

核心原則:註冊與註銷成對出現,生命周期對應

方案一:標準模式(推薦)

private BroadcastReceiver wifiReceiver;
private IntentFilter filter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    wifiReceiver = new WifiStateReceiver();
    filter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
    // 僅在 onCreate 註冊一次
    registerReceiver(wifiReceiver, filter);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // 對應註銷,防止內存洩漏
    if (wifiReceiver != null) {
        unregisterReceiver(wifiReceiver);
    }
}

方案二:動態註冊需配對(onResume/onPause)

若業務要求頁面可見時才監聽:

@Override
protected void onResume() {
    super.onResume();
    if (wifiReceiver == null) {
        wifiReceiver = new WifiStateReceiver();
        filter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
    }
    registerReceiver(wifiReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();
    if (wifiReceiver != null) {
        unregisterReceiver(wifiReceiver);
        wifiReceiver = null;  // 避免重複註銷
    }
}

方案三:使用標誌位防重複(不推薦,治標不治本)

private boolean isReceiverRegistered = false;

@Override
protected void onResume() {
    super.onResume();
    if (!isReceiverRegistered) {
        registerReceiver(wifiReceiver, filter);
        isReceiverRegistered = true;
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (isReceiverRegistered) {
        unregisterReceiver(wifiReceiver);
        isReceiverRegistered = false;
    }
}

崩潰原因深度解析

  • 重複註冊同一 Receiver 實例:Android 系統檢測到同一對象已註冊,拋出 IllegalArgumentException: Receiver already registered
  • 未註銷導致內存洩漏:Activity 銷毀後 Receiver 仍持有上下文引用
  • 多次註冊接收多份廣播:邏輯處理重複執行,導致狀態異常

最佳實踐清單

  1. 靜態註冊優先:清單文件聲明 <receiver>,系統管理生命周期
  2. 動態註冊成對:onCreate/onDestroy 或 onResume/onPause 成對調用
  3. Receiver 實例唯一:避免創建多個實例註冊同一 Action
  4. Android 8.0+ 限制:隱式廣播多數需動態註冊,注意適配
  5. 使用 LocalBroadcastManager:應用內通信更安全高效

針對原問題:將註冊移至 onCreate,註銷放入 onDestroy,即可徹底解決重複註冊導致的崩潰。

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