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,效率高

Previous:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注