Android 本地廣播 LocalBroadcastManager
重點提醒:
LocalBroadcastManager在 AndroidX 裡已經廢棄,官方推薦改用LiveData/Flow做應用程式內通訊,但面試依然會考。
一、本地廣播是什麼(對比全域廣播)
全域廣播(前面學的 sendBroadcast / sendOrderedBroadcast)
- 走系統 AMS,跨應用程式,所有 APP 都能收到這條廣播
- 安全隱患:資料容易被別的 App 攔截;別的 App 也可以偽造廣播攻擊我們的 App
本地廣播 LocalBroadcastManager
- 廣播只在目前 App 內部流轉,不會經過系統全域廣播機制,別的應用程式完全收不到 ✅ 優點:
- 安全:廣播不會洩漏到外部 App,外部 App 無法發送廣播進來冒充
- 高效:不需要跨程序與系統 AMS 互動,速度更快
- 不需要申請權限 限制:
- 只能動態註冊,不支援靜態註冊(在 AndroidManifest 裡寫 receiver 無效)
- 僅在同一個 App 內生效,不能跨程序、跨 App
- 不支援和系統廣播一起使用
二、完整程式碼拆解
1. 自定義接收器 MyReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "接收到本地廣播", Toast.LENGTH_LONG).show();
}
}
Code language: PHP (php)
2. Activity 中使用 LocalBroadcastManager
package cn.bamn.www.localcastdmeo;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager localBroadcastManager; // 本地廣播管理器參考
private IntentFilter intentFilter;
private MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 取得本地廣播管理器單例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = (Button) findViewById(R.id.btn_send);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
// 建構 Intent Action,發送本地廣播
Intent intent = new Intent("com.foxdevelop.www.LocalCastDemo.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
// 動態註冊本地廣播接收器
intentFilter = new IntentFilter();
intentFilter.addAction("com.foxdevelop.www.LocalCastDemo.LOCAL_BROADCAST");
myReceiver = new MyReceiver();
localBroadcastManager.registerReceiver(myReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 必須反註冊!防止記憶體洩漏
localBroadcastManager.unregisterReceiver(myReceiver);
}
}
Code language: JavaScript (javascript)
核心 API:
LocalBroadcastManager.getInstance(context):取得實例(單例)registerReceiver(receiver, intentFilter):動態註冊接收器sendBroadcast(intent):發送本地無序廣播;sendOrderedBroadcast()本地有序廣播unregisterReceiver():頁面銷毀取消註冊,必寫,記憶體洩漏大坑
三、本地廣播、無序全域廣播、有序全域廣播 對比彙總
| 類型 | 通訊範圍 | 是否跨 App | 能否截斷 | 註冊方式 | 底層機制 |
|---|---|---|---|---|---|
| 全域無序廣播 sendBroadcast | 全域 | 可以跨 App | 不能 abort | 靜態+動態 | 系統 AMS 跨程序 |
| 全域有序廣播 sendOrderedBroadcast | 全域 | 可以跨 App | abortBroadcast 截斷 | 靜態+動態 | 系統 AMS 跨程序,依 priority 串行 |
| 本地廣播 LocalBroadcastManager | 本應用程式內 | 不能跨 App | 支援有序廣播截斷 | 僅動態註冊 | 記憶體內分發,不走 AMS,效率高 |
Android 本地廣播
Previous: 有序廣播