開發 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);
}
}
若業務要求頁面可見時才監聽:
@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;
}
}
IllegalArgumentException: Receiver already registered<receiver>,系統管理生命周期針對原問題:將註冊移至 onCreate,註銷放入 onDestroy,即可徹底解決重複註冊導致的崩潰。