BroadcastReceiver基础知识

什么是广播

在Android中,广播是一种广泛运用的在应用程序之间传输信息的机制,Android中我们要发送的广播内容是一个Intent,这个Intent中可以携带我们要传送的数据。比如我们可以使用广播来实现Activity与Service之间的通信,而不必使用bindService;还有一个常用的场景就是当我们在应用中退出登录后,需要调到登录界面,而之前的主界面可以发送一个广播来通知主界面销毁自己。

广播的种类

广播一共有以下3种类型:

  1. Normal Broadcast:普通广播,调用方法是Context.sendBroadcast
  2. System Broadcast:系统广播(开机、电量低),调用方法是Context.sendOrderedBroadcast
  3. Local Broadcast:本地广播,只在自身APP内传播,内部实现机制是Handler

广播的使用场景

  1. 同一个App具有多个进程的不同组件之间的消息通信,定位服务一般都会在一个单独的进程中,通过广播告诉其他进程定位信息
  2. 不同app之间的组件之间的消息通信,比如系统电话

实现广播

实现广播有两种方式:

  1. 静态注册:
    在AndroidManifest.xml里通过标签声明


//用于指定此广播接收器将接收的广播类型
//本示例中给出的是用于接收网络状态改变时发出的广播
 

    

创建一个类继承自BroadcastReciver,然后复写其中的onReceive()方法,判断相应的action即可。
静态注册的广播会一直存在,不管app是否是运行的,只要接收到注册的广播就会执行onRecive里的代码。

  1. 动态注册:
    需要在activity中动态的registerReceiver
// 选择在Activity生命周期方法中的onResume()中注册
@Override
  protected void onResume(){
      super.onResume();

    // 1. 实例化BroadcastReceiver子类 &  IntentFilter
     mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
     IntentFilter intentFilter = new IntentFilter();

    // 2. 设置接收广播的类型
    intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);

    // 3. 动态注册:调用Context的registerReceiver()方法
     registerReceiver(mBroadcastReceiver, intentFilter);
 }


// 注册广播后,要在相应位置记得销毁广播
// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)
// 当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
// 当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
 @Override
 protected void onPause() {
     super.onPause();
      //销毁在onResume()方法中的广播
     unregisterReceiver(mBroadcastReceiver);
     }
}

相比于静态注册,动态注册的广播跟随着activity的生命周期,同时为了防止内存溢出,需要在activity的onDestory方法中调用unregisterReceiver(mBroadcastReceiver);

广播的内部实现机制

  1. 自定义广播接收者BroadcastReceiver,并复写onReceive()方法
  2. 通过Binder机制向AMS(Activity Manager Service)进行注册
  3. 广播发送者通过Binder机制向AMS发送广播
  4. AMS查找符合相应条件的BroadcastReceiver,将广播发送到BroadcastReceiver相应的消息循环队列中
  5. 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceiver方法

本地广播的优点

  1. 使用它发送的广播将只在自身app内传播,因此你不必担心泄漏隐私数据
  2. 其他App无法对你的app发送广播,因为你的app根本就不可能接收到非自身应用发送的该广播,因此不必担心有安全漏洞可以利用
  3. 它比系统广播更加高效

LocalBroadcastManager源码分析

首先我们看源码要有目的的去看,而且入口点是你调用的方法,从该方法去看
这里的入口就是registerReceiver

public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        synchronized (mReceivers) {
            //保存的是filter和receiver
            ReceiverRecord entry = new ReceiverRecord(filter, receiver);
            ArrayList filters = mReceivers.get(receiver);
            if (filters == null) {
                filters = new ArrayList<>(1);
                mReceivers.put(receiver, filters);
            }
          
            filters.add(entry);
            for (int i=0; i entries = mActions.get(action);
                if (entries == null) {
                    entries = new ArrayList(1);
                    mActions.put(action, entries);
                }
                entries.add(entry);
            }
        }
    }

再来看发送广播的方法,这里只截取的关键的一部分

if (receivers != null) {
                   for (int i=0; i

可以看到它内部是使用Handler来发送的,这就说明了它比系统广播更加的高效。

你可能感兴趣的:(BroadcastReceiver基础知识)