Android 本地廣播

Android 本地廣播 LocalBroadcastManager

重點提醒:LocalBroadcastManager 在 AndroidX 裡已經廢棄,官方推薦改用 LiveData / Flow 做應用程式內通訊,但面試依然會考。

一、本地廣播是什麼(對比全域廣播)

全域廣播(前面學的 sendBroadcast / sendOrderedBroadcast)

  • 走系統 AMS,跨應用程式,所有 APP 都能收到這條廣播
  • 安全隱患:資料容易被別的 App 攔截;別的 App 也可以偽造廣播攻擊我們的 App

本地廣播 LocalBroadcastManager

  • 廣播只在目前 App 內部流轉,不會經過系統全域廣播機制,別的應用程式完全收不到 ✅ 優點:
  1. 安全:廣播不會洩漏到外部 App,外部 App 無法發送廣播進來冒充
  2. 高效:不需要跨程序與系統 AMS 互動,速度更快
  3. 不需要申請權限 限制:
  4. 只能動態註冊,不支援靜態註冊(在 AndroidManifest 裡寫 receiver 無效)
  5. 僅在同一個 App 內生效,不能跨程序、跨 App
  6. 不支援和系統廣播一起使用

二、完整程式碼拆解

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全域可以跨 AppabortBroadcast 截斷靜態+動態系統 AMS 跨程序,依 priority 串行
本地廣播 LocalBroadcastManager本應用程式內不能跨 App支援有序廣播截斷僅動態註冊記憶體內分發,不走 AMS,效率高

Android 本地廣播

Previous:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *