Android Broadcast Receiver 广播

Android Broadcast Receiver 广播

广播(Broadcast)是Android中的一种机制,允许应用程序之间传递消息。广播在Android中扮演着重要角色,能够在不同的组件间传递信息,无论是应用内部还是跨应用。下面我将详细解释广播的机制,并提供几个示例,按照难度逐步增加。

广播机制详细解释

1. 广播的基本概念

广播允许应用程序在系统中发送和接收消息。系统的广播可以是应用程序间的,也可以是系统内部的。广播机制基于发布/订阅模式,使得广播接收者能够接收到发送者发送的消息。

四大角色:

  • 广播发送者(Broadcast Sender): 发送广播消息的组件,可以是任何应用或系统组件。
  • 广播接收者(Broadcast Receiver): 接收广播消息的组件。
  • 消息中心(AMS - Activity Manager Service): 负责管理广播的发送和接收,调度广播接收者。
  • IntentFilter: 用于指定广播接收者能够接收哪些广播消息。

2. 广播的工作流程

  1. 广播接收者注册: 广播接收者通过Binder机制在AMS中注册。·
  2. 广播发送: 广播发送者通过Binder机制向AMS发送广播。
  3. 广播分发: AMS根据广播的IntentFilter和权限,找到合适的广播接收者,并将广播发送到相应的消息循环队列。
  4. 广播接收: 广播接收者从消息循环队列中获取广播,并执行onReceive()方法。

3. 广播的注册

广播可以通过两种方式注册:静态注册和动态注册。

  • 静态注册: 在AndroidManifest.xml文件中注册,适用于应用启动时需要接收的广播。注意,Android 8.0 之后,静态注册受到限制,只能接收系统广播。
  • 动态注册: 通过registerReceiver()方法在代码中注册,适用于运行时需要接收的广播。

示例

示例 1:静态注册广播

  1. 创建广播接收器
public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "MyReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.e(TAG, "onReceive: " + msg);
    }
}
  1. 在清单文件中注册
<receiver android:name=".receiver.MyReceiver"
            android:exported="true">
        </receiver>
<!--
		使用虚拟机Android版本为8以下才能出现效果
        Android 8.0(Oreo)之前:任何应用程序只要发送匹配的广播(即具有相同的 action),都可以被这个接收器接收。
        为 true 表示这个广播接收器可以接收到来自其他应用的广播。如果设置为 false,则只有在同一应用内部发送的广播才会被这个接收器接收。
        Android 8.0(Oreo)及以后版本:静态注册的广播接收器只能接收到系统广播(如电池状态变化、网络状态变化等)。自定义广播需要使用动态注册的方式来接收。
-->
  1. 发送广播
 findViewById(R.id.btn).setOnClickListener(v->{
            Log.d("TAG", "onStart: -->");
            Intent intent = new Intent();
            intent.setAction("com.jing.mybroadcastreceiver");
            intent.putExtra("msg", "你好啊");
            sendBroadcast(intent);
            Log.d("TAG", "onFinish: -->");
        });

示例 2:动态注册广播

  1. 创建广播接收器
public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "MyReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        if ("com.jing.mybroadcastreceiver.myReceiver".equals(intent.getAction())) {
            String msg = intent.getStringExtra("msg");
            Log.e(TAG, "onReceive: " + msg);
        }
    }
}
  1. 在Activity中动态注册广播
public class MainActivity extends AppCompatActivity {

    private MyReceiver myReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //点击按钮发送广播
        findViewById(R.id.btn).setOnClickListener(v -> {
            Log.d("TAG", "onStart: -->");
            Intent intent = new Intent("com.jing.mybroadcastreceiver.myReceiver");
            intent.putExtra("msg", "Hello, world!");
            sendBroadcast(intent);
            Log.d("TAG", "onFinish: -->");
        });
        
        myReceiver = new MyReceiver();
        //创建接收器实例
        IntentFilter intentFilter = new IntentFilter();
        //指定接收器的 Intent 类型。它可以让 BroadcastReceiver 监听特定的广播动作。
        intentFilter.addAction("com.jing.mybroadcastreceiver.myReceiver");
        //将特定的动作(Action)添加到 IntentFilter 中
        registerReceiver(myReceiver, intentFilter);
        //注册广播接收器
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myReceiver != null) {
            //注销广播
            unregisterReceiver(myReceiver);
        }
    }
}

示例 3:有序广播

  1. 创建有序广播接收器
//广播接收器一
public class MyOrderBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyOrderBroadcastReceive";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        String msg = intent.getStringExtra("msg");
        Log.e(TAG, "MyOrderBroadcastReceiver-onReceive: " + msg + " | Action: " + action);
    }
}
//广播接收器二
public class MyOrderBroadcastReceiverTwo extends BroadcastReceiver {
    private static final String TAG = "MyOrderBroadcastReceive";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        String msg = intent.getStringExtra("msg");
        Log.e(TAG, "MyOrderBroadcastReceiverTwo-onReceive: " + msg + " | Action: " + action);
        //测试中断将下列if注释
        if (action.equals("BROADCAST_ACTION")) abortBroadcast();

    }
}

  1. 在清单文件中注册有序广播
<receiver android:name=".receiver.MyOrderBroadcastReceiver"
            android:exported="false">
            <intent-filter android:priority="1">
                <action android:name="BROADCAST_ACTION" />
            </intent-filter>
        </receiver>

        <receiver android:name=".receiver.MyOrderBroadcastReceiverTwo"
            android:exported="false">
            <intent-filter android:priority="2">
                <action android:name="BROADCAST_ACTION" />
            </intent-filter>
        </receiver>
  1. 发送有序广播
        findViewById(R.id.btn).setOnClickListener(v -> {
            Log.d("TAG", "onStart: -->");
            Intent intent = new Intent("BROADCAST_ACTION");
            intent.putExtra("msg", "hello word");
            sendOrderedBroadcast(intent, null);
            Log.d("TAG", "onFinish: -->");
        });

示例 4:应用内广播(LocalBroadcastManager)

需要引入依赖
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
  1. 创建广播接收器

        private BroadcastReceiver myReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 处理广播
                if ("com.jing.ACTION_CUSTOM_BROADCAST".equals(intent.getAction())){
                    String message = intent.getStringExtra("message");
                    Log.d("MainActivity", "Broadcast received!-->"+message);
                }
            }
        };
    
  2. 注册广播接收器

    LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, new IntentFilter("com.jing.ACTION_CUSTOM_BROADCAST"));    
    
  3. 发送广播

findViewById(R.id.btn).setOnClickListener(v->{
            Intent intent = new Intent("com.jing.ACTION_CUSTOM_BROADCAST");
            intent.putExtra("message","hello , LocalBroadcastManager");
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        });

注意: LocalBroadcastManager 主要用于应用内部广播,确保广播只在同一个应用内部传播。

总结

广播机制在Android中扮演着重要的角色,通过发送和接收广播,组件能够实现消息传递和事件通知。通过静态注册和动态注册两种方式,开发者可以灵活地使用广播。而有序广播和应用内广播(LocalBroadcastManager)提供了更细粒度的控制和安全性。

代码地址

lxj/MyBroadcastReceiver (gitee.com)

posted @ 2024-08-06 11:05  疾风不问归途  阅读(514)  评论(0)    收藏  举报