BroadcastReceiver详解-飞
发布时间: 2023-07-06
1、广播的类型

广播分为标准广播和有序广播。

1.1、标准广播

标准广播是一种完全异步执行的广播,在广播发出之后,所有的BroadcastReceiver几乎在同一时刻收到这个广播消息,它们之间没有先后顺序,这种广播的效率较高,并且不能被拦截。

1.2、有序广播

有序广播是一种完全同步的广播,在广播发出后只能有一个BroadcastReceiver能接收到这个广播消息,当这个BroadcastReceiver中的逻辑执行完毕后,广播才能继续向下传递。所以这个广播是有顺序的,所以这种广播也是可以被拦截的,如果被拦截了后面的BroadCastReceiver则不能收到广播消息了。

2、系统广播的注册

广播的注册分为动态注册和静态注册。

2.1、动态注册系统广播1、创建BroadCastReceiver的子类,在onReceive()编写相应的逻辑。
class TimeChangeReceiver : BroadcastReceiver() {    override fun onReceive(context: Context?, intent: Intent?) {        context?.let {            showToast(it, "收到了时间变化的广播")        }    }}
2、通过registerReceiver()注册广播监听3、在页面关闭时记得通过unregisterReceiver()注销广播监听,否则会因广播持有Activity引用导致内存泄露。
class ReceiverActivity : AppCompatActivity() {    var receiver:TimeChangeReceiver?=null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_receiver)        btn_regist.setOnClickListener {            val intentFilter = IntentFilter()            intentFilter.addAction(Intent.ACTION_TIME_TICK)             receiver = TimeChangeReceiver()            registerReceiver(receiver, intentFilter)        }    }    override fun onDestroy() {        super.onDestroy()        receiver?.let {            unregisterReceiver(it)        }    }}

这样我们就注册系统时间变化的广播,在时间变化时广播了。

2.2、静态注册系统广播

动态注册广播可以很方便的注册和注销广播,但是这都是基于程序启动的状态下进行的,那么能不能在程序未启动时就能接收到广播呢?这就用到了静态注册广播,但是有很多恶意应用通过静态注册的方法监听系统的广播,然后频繁的唤醒应用导致用户手机的性能和电量,在Android8.0后,所有隐式广播都不能通过静态注册了,隐式广播是指没有指定那个应用程序接收广播。而大多数系统广播都是隐式广播,但是也有少数的特殊广播仍然能允许通过静态注册的方法注册,比如:开机广播,下面我们就通过静态注册的方法注册系统开机的广播。

1、创建BootcastReceiver继承BroadCastReceiver
class BootReceiver:BroadcastReceiver() {    override fun onReceive(context: Context?, intent: Intent?) {        context?.let {           Toast.makeText(context,"开启",Toast.LENGTH_LONG).show()        }    }}
2、在Manifest中注册receiver
 <uses-permission android:/>    <application>   <receiver android:                  android:exported="true"                  android:enabled="true">            <intent-filter>                <action android:/>            </intent-filter>        </receiver>    </application>

这样就完成了开机启动的静态广播的注册,不过为了保护用户的安全和隐私,需要对权限进行声明,在接收系统开启广播需要在Manifest中配置权限。
另外需要注意,在onReceive()不能执行耗时操作,onReceive()默认是在主线程中,进行耗时会阻塞主线程,如果非要执行耗时操作最好开启一个服务在服务中进行耗时操作,不建议开启线程来处理耗时操作,因为BroadCastReceiver的生命周期很短,可能在子线程结束前BroadCastReceiver已经退出,如果当BroadCastReceiver所在的进程结束,虽然该进程中可能有用户启动的新线程,但是由于该进程内没有活动的组件,系统会在内存紧张的时候,优先结束掉该进程,这就会导致BroadCastReceiver启动的子线程不能执行完。

3、自定义广播的动态注册和静态注册

自定义广播和系统广播的区别就在于,广播消息的发送是我们手动触发的,而系统广播是由系统触发的。下面我们简单看下使用过程。

3.1、动态注册自定义广播

代码如下:

class ReceiverActivity : AppCompatActivity() {    var receiver:DynamicCustomReceiver?=null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_receiver)        btn_regist.setOnClickListener {            val intentFilter = IntentFilter()            intentFilter.addAction(DynamicCustomReceiver::class.java.name)             receiver = DynamicCustomReceiver()            registerReceiver(receiver, intentFilter)        }        btn_send_broad.setOnClickListener {            val intent=Intent(Dynami(中文邮件格式:邮件的主题是为了让收件人看到邮件之后对该邮件有个大体了解,确定邮件的紧急、重要程度、有效、有用性的;所以在写主题的时候最主要的突出 什么事、重要程度等关键信息;可以按照以下方式和思路去写:格式:修饰词+邮件内容+时间+发件人。如果有必要的话还可以在主题上加上紧急程度和邮件的主体内容,清晰明了。)cCustomReceiver::class.java.name)            sendBroadcast(intent)        }    }    override fun onDestroy() {        super.onDestroy()        receiver?.let {            unregisterReceiver(it)        }    }}

DynamicCustomReceiver

class DynamicCustomReceiver : BroadcastReceiver() {    override fun onReceive(context: Context?, intent: Intent?) {        context?.let {            showToast(it, "自定义广播动态注册")        }

微信