1 BroadcastReceiver是什么
BroadcastReceiver(广播接收器)即广播,是一个全局的监听器。
Android 广播分为两个角色:广播发送者、广播接受者。
2 广播类型
广播按照类型分为两种,一种是全局广播,另一种是本地广播
全局广播:就是发出的广播被其他任意应用程序接收,或者可以接收来自其他任意应用程序的广播。
本地广播:则是只能在应用程序内部进行传递的广播,广播接收器也只能接收内部的广播,不能接收其他应用程序的广播
广播按照机制分两种,一种是标准广播,一种是有序广播
标准广播:是一种异步的方式来进行传播的,所有接收者都会接收事件,不可以被拦截,不可以被修改
有序广播:是一种同步执行的广播,按照优先级,一级一级的向下传递,接收者可以修改广播数据,也可以终止广播事件。
3 BroadcastReceiver原理
// 模型
基于消息的发布/订阅事件模型,使用了设计模式中的观察者模式;
// 模型角色:
1.消息订阅者
2.消息发布者
3.消息中心(AMS,即Activity Manager Service)
// 原理描述
1.广播接收者 通过Binder机制在AMS注册
2.广播发送者 通过Binder机制向AMS发送广播
3.AMS根据广播发送者要求,在已注册列表中,寻找合适的广播接收者(寻找依据:IntentFilter/Permission)
4.AMS将广播发送到合适的广播接收者相应的消息循环队列中
5.广播接收者通过消息循环拿到此广播,并回调onReceive()
4 动态注册
给出一个示例:用BroadcastReceiver实现2个activity之间的通信,点击A页面,跳转到B页面,在B页面发送广播,A页面收广播
//AActivity.java package com.example.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.widget.Toast; import androidx.annotation.Nullable; public class AActivity extends AppCompatActivity { private DynamicBRReceiver dynamicBRReceiver; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.a_activity_layout); // 动态注册广播接收器 dynamicBRReceiver = new DynamicBRReceiver(); IntentFilter itFilter = new IntentFilter(); itFilter.addAction("com.example.broadcasttest.DynamicBRReceiver"); registerReceiver(dynamicBRReceiver, itFilter); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(AActivity.this, BActivity.class); startActivity(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(dynamicBRReceiver); } }
// BActivity.java package com.example.myapplication; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; public class BActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.b_activity_layout); findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //发送广播 // 动态注册方式发送 Intent intent = new Intent("com.example.broadcasttest.DynamicBRReceiver"); sendBroadcast(intent); } }); } } ```java // DynamicBRReceiver.java package com.example.myapplication; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class DynamicBRReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "DynamicBRReceiver: 收到广播!!!", Toast.LENGTH_SHORT).show(); } }
注意:
1.广播接收器接收到相应广播后,会自动回调onReceive方法
2.一般情况下,onReceive方法会涉及与其它组件之间的交互,如发送Notification、启动Service
3.默认情况下,广播接收器运行在UI线程,因此onReceive方法不能执行耗时操作,否则将导致ANR。
5 静态注册
静态注册的方式需要在AndroidManifest.xml中注册
<receiver android:name="com.example.myapplication.StaticBRReceiver"> <intent-filter> <action android:name="com.example.broadcasttest.StaticBRReceiver" /> </intent-filter> </receiver>
// BActivity.java package com.example.myapplication; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; public class BActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.b_activity_layout); findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 静态注册方式发送 Intent intent = new Intent(); intent.setComponent(new ComponentName(BActivity.this, StaticBRReceiver.class)); sendBroadcast(intent); } }); } }
// StaticBRReceiver.java package com.example.myapplication; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; // 静态注册 public class StaticBRReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "StaticBRReceiver: 收到广播!!!", Toast.LENGTH_SHORT).show(); } }
6 动态注册和静态注册的区别
// 使用方式:
静态注册是在AndroidManifest文件中使用receiver标签注册的,动态注册是在代码中调用Context.registerReceiver方法
// 特点:
静态注册是常驻广播,不受任何组件的生命周期影响(应用程序关闭后,依旧可以会被系统调用),缺点是耗电,占内存
动态注册是非常驻广播,灵活,跟随组件的生命周期变化(组件结束=广播结束,在组件结束之前必须移除广播接收器)
// 应用场景:
当需要时刻监听广播时,使用静态注册方式;当只需要在特定时刻监说明听广播时,使用动态注册的方式