Android的广播接收者

介绍

  广播接收者是Android的四大组件,与其他组件不同,广播接收者可以动态注册,用于接收到广播后处理,也可起着进程间通信作用,了解到Android用多种通信方式,那为什么还要搞个广播接收者让我们学呢?
  广播机制有着牢固的地位,广播接收者和发送者是无需知道对方的存在和位置,使用简单,使得应用程序高内聚低耦合,简化代码,降低使用风险,减少维护工作。

工作原理:
在这里插入图片描述

生命周期注意事项:

  广播的生命周期极其短暂,最好不要做耗时操作,超过10s会弹出ANR,而且在如果是动态注册,则必须在Activity销毁前使用unregisterReceiver注销广播,否则报异常
ANR原理http://gityuan.com/2016/07/02/android-anr/

使用方法

静态注册
1、继承BroadcastReceiver,重写onReceive()

class MyBroadcastReceiver: BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        Log.i("receiver",intent?.getStringExtra("msg"))
    }
}	

2、清单文件:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.MyBroadcast"></action>
    </intent-filter>
</receiver>

动态注册

class MainActivity : AppCompatActivity() {
    var myBroadcastReceiver:MyBroadcastReceiver? = MyBroadcastReceiver()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val filter = IntentFilter()
        filter.addAction("android.intent.action.MyBroadcast")
        registerReceiver(myBroadcastReceiver, filter)
    }
    override fun onDestroy() {
        unregisterReceiver(myBroadcastReceiver)
        myBroadcastReceiver = null
        super.onDestroy()
    }
}

两种注册方式区别:

  • 静态注册的广播运行一次后,就一直会处于广播接收状态,即使应用程序退出。
  • 动态注册无需再清单文件写(同时他是andorid四大组件中唯一一个可以不用在清单文件注册的),注销后就不能再接收广播了。
  • 如果是静态注册的广播,onReceive里的context为ReceiverRestrictedContext对象实例,所在如果在这里要启动一个Activity的话(调用startActivity),需要在intent中添加Intent.FLAG_ACTIVITY_NEW_TASK;
  • 如果是动态注册,registerReceiver是android.content.ContextWrapper类中的方法,Activity 和Service都继承了ContextWrapper,onReceive里的context即是调用者的上下文,所以可以直接调用。
  • 对于动态广播,有注册就必然得有注销,否则会导致内存泄露,假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。

特殊的广播接收者:
  频繁发广播的需要动态注册,如锁屏,电量变化,网络连接,如果是静态注册会无效。

发送广播

1. 无序广播

val intent = Intent("android.intent.action.MyBroadcast")
intent.putExtra("msg", "普通广播")
sendBroadcast(intent)

2. 有序广播
需要在intent-filter里设置优先级
静态广播需要再清单文件设置:

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter android:priority="100">
        <action android:name="android.intent.action.MyBroadcast"></action>
    </intent-filter>
</receiver>
<receiver android:name=".MyBroadcastReceiver2">
    <intent-filter android:priority="50">
        <action android:name="android.intent.action.MyBroadcast"></action>
    </intent-filter>
</receiver>

动态注册的这样设置:

filter.setPriority(100);

数字越大优先级越高,同优先级的广播接收者,动态优先于静态
发送:

val intent = Intent("android.intent.action.MyBroadcast")
intent.putExtra("msg", "有序")
sendOrderedBroadcast(intent,null);

之后即可在自个儿广播接收者拦截:

class MyBroadcastReceiver: BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.i("receiver",intent?.getStringExtra("msg"))
        abortBroadcast()
        resultData = "有序广播版本2"
    }
}

可见MyBroadcastReceiver拦截后修改了resultData,之后广播继续往下传递,只不过传到另一个广播接收者的参数变成了"有序广播版本2"。

全局广播和应用内广播
注册广播时intent-filter的exported属性设置可以设置,默认true为全局广播

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值