Android四大组件之BroadcastReceiver

来源:互联网 发布:网络销售的薪资 编辑:程序博客网 时间:2024/06/03 13:36

BroadcastReceiver广播接收者是Android四大组件之一。是一种广泛运用在组件与组件、跨应用程序间的数据通信
BroadcastReceiver广播注册有两种类型:静态注册、动态注册
BroadcastReceiver广播发送有四种类型:普通广播、有序广播、系统广播、App应用内广播

自定义BroadcastReceiver创建

  1. 自定义广播接收器继承基类BroadcastReceivre
  2. 实现抽象方法onReceive(context, intent)方法
public class MyBroadcastReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        String name = intent.getStringExtra("name");        Log.d("MyBroadcastReceiver", "context:"+context.toString());        Log.d("MyBroadcastReceiver", "name:"+name);    }}

注意
onReceive方法是运行在UI线程,不能执行太耗时的操作(超过10s)。否则将ANR

BroadcastReceiver注册类型

静态注册
在AndroidManifest.xml中进行注册

<receiver    android:name=".MyBroadcastReceiver"    android:enabled="true"    android:exported="true">    <intent-filter>        <action android:name="this_is_myReceiver"/>    </intent-filter></receiver>

enabled代表是否能够实例化这个广播接收器,默认值是true
exported代表是否接收其他App的发出的广播
默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false。(activity、service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者application user id为界,而非进程为界(一个应用中可能含有多个进程)
intent过滤器,指定可以匹配哪些intent, 可以自定义 也可用系统的

发送广播

Intent intent = new Intent();intent.setAction("this_is_myReceiver");intent.putExtra("name", "静态注册广播");sendBroadcast(intent);//发送广播

注意

Android 3.1之前Android不能自动销毁广播接收器,也就是说当应用程序关闭后,还是会接收广播,Android 3.1开始有可能不再成立 。
Android 3.1开始系统在Intent与广播相关的flag增加了参数,分别是FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES。FLAG_INCLUDE_STOPPED_PACKAGES:包含已经停止的包(停止:即包所在的进程已经退出)
FLAG_EXCLUDE_STOPPED_PACKAGES:不包含已经停止的包
自Android3.1开始,系统本身则增加了对所有app当前是否处于运行状态的跟踪。在发送广播时,不管是什么广播类型,系统默认直接增加了值为FLAG_EXCLUDE_STOPPED_PACKAGES的flag,导致即使是静态注册的广播接收器,对于其所在进程已经退出的app,同样无法接收到广播。
由此,对于系统广播,由于是系统内部直接发出,无法更改此intent flag值,因此,3.1开始对于静态注册的接收系统广播的BroadcastReceiver,如果App进程已经退出,将不能接收到广播
但是对于自定义的广播,可以通过复写此flag为FLAG_INCLUDE_STOPPED_PACKAGES,使得静态注册的BroadcastReceiver,即使所在App进程已经退出,也能能接收到广播,并会启动应用进程,但此时的BroadcastReceiver是重新新建的。

Intent intent = new Intent();intent.setAction(BROADCAST_ACTION);intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);intent.putExtra("name", "qqyumidi");sendBroadcast(intent);

动态注册
代码中通过registerReceiver()注册,当程序关闭时,调用unregisterReceiver()进行销毁

MyBroadcastReceiver mReceiver = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();filter.addAction("this is broadcast");registerReceiver(mReceiver, filter);Intent intent = new Intent();intent.setAction("this is broadcast");intent.putExtra("name", "动态注册广播");sendBroadcast(intent);//发送广播

取消广播

protected void onDestroy() {    super.onDestroy();    unregisterReceiver(mReceiver);}

LocalBroadcastManager本地广播
前面两种广播都是全局的,所有应用程序都可以接收到广播,这样很容易会引起安全问题,所以,Android引入了一套本地广播机制,
相比于全局广播,App应用内广播优势体现在

  1. 本地广播无法通过静态注册来接收,相比系统全局广播更加高效
  2. 发送的广播只能在应用程序内传播,不会泄露给其他App,确保隐私数据不会泄露
  3. 其他App也无法向自己App发送该广播,不用担心其他App会来搞破坏,安全性更高

代码中注册本地广播

LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);//获得LocalBroadcastManager实例mLocalReceiver = new MyLocalBroadcastReceiver();//自定义广播接收器继承基类BroadcastReceivreIntentFilter filter = new IntentFilter();filter.addAction("this is localBroadcastReceiver");mLocalBroadcastManager.registerReceiver(mLocalReceiver, filter);//注册广播Intent intent = new Intent();intent.setAction("this is localBroadcastReceiver");intent.putExtra("name", "应用内本地广播注册");mLocalBroadcastManager.sendBroadcast(intent);//发送广播

取消注册

protected void onDestroy() {    super.onDestroy();    unregisterReceiver(mReceiver);    mLocalBroadcastManager.unregisterReceiver(mLocalReceiver);}

注意

  • 在广播中启动activity的话,需要为intent加入FLAG_ACTIVITY_NEW_TASK的标记,不然会报错,因为需要一个栈来存放新打开的activity
  • 广播中弹出AlertDialog的话,需要设置对话框的类型为:TYPE_SYSTEM_ALERT不然是无法弹出的

广播发送类型

普通广播

普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的 接收广播。

Intent intent = new Intent();intent.setAction("this_is_myReceiver");intent.putExtra("name", "静态注册广播");sendBroadcast(intent);

有序广播
有序广播每次先发送到优先级最高的接受者里,然后由高至低进行传播,优先级高德接受者有权终止广播、修改广播。
优先级设置

  • 在AndroidManifest.xml中intent-filter里面设置android: priority=”xxx”
  • 在java代码中设置setPriority(xxx)
Intent intent = new Intent();intent.setAction("this_is_myReceiver");intent.putExtra("name", "静态注册广播");sendOrderedBroadcast(intent,null);//如果是该自定义的广播接收者发送广播,第二个参数一般为null

拦截广播
abortBroadcast();
有序广播才能拦截

不同注册方式的广播接收器回调onReceive(context, intent)中的context具体类型

1:对于静态注册的ContextReceiver,回调onReceive(context, intent)中的context具体指的是ReceiverRestrictedContext
2:对于全局广播的动态注册的ContextReceiver,回调onReceive(context, intent)中的context具体指的是Activity Context
3:对于通过LocalBroadcastManager动态注册的ContextReceiver,回调onReceive(context, intent)中的context具体指的是Application Context

原创粉丝点击