当前位置:   article > 正文

【Android Broadcast】BroadcastReceiver_android 发送广播

android 发送广播

作为安卓中的四大组件广播的作用也是非常大的,听名字我们或许就知道他的功能啦!接下来就回顾、总结下这个重要的组件。

在这里插入图片描述

一、简介

1、分类
  • 广播发送者:发送广播,发布广播后,订阅过的接收者就可以接收到广播。
  • 广播接收者:接收广播(想要接收广播,必须要注册即订阅相应的广播)
2、BroadcastReceiver定义

BroadcastReceiver是一个全局的监听器,它可以监听安卓系统、其他App、自己App发出的广播。并作出相应的处理。是安卓的四大组件之一。

3、BroadcastReceiver的作用

BroadcastReceiver就是广播接收者,接收广播。

4、应用场景

(1)同一app内部的同一组件内的消息通信(单个或多个线程之间)
(2)同一app内部的不同组件之间的消息通信(单个进程)
(3)同一app有不同的组件,且运行在不同的进程中(多个进程之间)
(4)不同app之间的组件之间消息通信(多个进程之间)
(5)Android系统在特定情况下与App之间的消息通信

  • 场景1实际上没必要用广播实现。通过扩展作用于的范围、使用接口回调、使用handler机制都可以解决
  • 场景2同一app内部的不同组件之间的消息通信(单个进程),对于此类需求,在有些教复杂的情况下单纯的依靠基于接口的回调等方式不好处理,此时可以直接使用EventBus等,相对而言,EventBus由于是针对统一进程,用于处理此类需求非常适合,且轻松解耦。
  • 场景3、4、5可以使用广播
5、原理基于

发布者、订阅者,一听我们就想到了“观察者设计模式”,没错安卓中的广播机制就是基于观察者模式的,只不过安卓中通过“消息中心ASM”来处理沟通广播接收者、发送者。为啥要把ASM设计为消息中心呢?

  • 这就考虑到广播发送者、接收者的作用了即发送、接收全局消息。这时肯定不局限与同一个app内的进程中啦。而安卓的ipc机制底层又是基于Binder的所以广播发送者、广播接收者、ASM之间就通过Binder联系起来啦!
  • 由于四大组件的启动都牵涉到ASM所以,我们启动广播也是离不开他的,ASM便可根据发送者的要求在安卓的注册列表中寻找合适的广播(寻找依据: 广播的权限、intent filter 内的匹配规则)

(1)原理草图

在这里插入图片描述

1、广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;
2、广播发送者通过binder机制向AMS发送广播;
3、AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
4、消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。

二、使用流程

1、创建广播接收者

步骤:
1、自定义类继承BroadcastReceiver
2、重写onReceiver方法
3、等待广播发送者发送广播,这样BroadcastReceiver的onReceiver就会回调。

/**
 * Created by sunnyDay on 2019/8/13 18:09
 */
public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "收到广播", Toast.LENGTH_SHORT).show();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
2、广播的注册

(1)动态注册

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();

        IntentFilter filter = new IntentFilter();
        filter.addAction("sunny.day.custom.broadcast"); //添加过滤条件,接收广播
        MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
        registerReceiver(mBroadcastReceiver, filter);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    /**
     * 点击按钮发送自定义广播
     * */
    public void send(View view) {
        Intent intent = new Intent();
        intent.setAction("sunny.day.custom.broadcast");// 发送者定义 过滤条件
        sendBroadcast(intent);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        // activity 销毁时解注册
        unregisterReceiver(mBroadcastReceiver);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

说明:

  • 如上通过sendBroadcast 就可发送一条自定义广播。
  • 通过代码中registerReceiver就可注册想要接收的广播。当有广播发送时,广播接收者就会收到。
  • 上面的action是我们自己定义的字符串、其实安卓系统也定义了很多,比如“android.net.conn.CONNECTIVITY_CHANGE”网络状态变化。我们也可以监听系统广播。监听系统广播时只需要注册下系统广播即可。当系统发送广播时,我们就可以收到。

注意:

  • 动态注册的广播要在activity退出时解注册,否则会造成内存泄漏。
  • 广播接收器也是运行在UI线程,因此,onReceive方法中不能执行太耗时的操作。否则将因此ANR。一般情况下,根据实际业务需求,onReceive方法中都会涉及到与其他组件之间的交互,如发送Notification、启动service等。

广播解注册的时机:

不在onCreate() & onDestory() 或 onStart() & onStop()注册、注销是因为:

当系统因为内存不足(优先级更高的应用需要内存)要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。

假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。

(2)静态注册

在安卓的manifest中通过receiver节点下添加 intent-filter,然后在intent-filter中添加过滤条件。

        <receiver android:name=".MyBroadcastReceiver"
            android:exported="false">
            <intent-filter >
                // 自定义一个action
                <action android:name="sunny.day.custom.broadcast" />
            </intent-filter>
        </receiver>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

receiver节点的属性:
1、exported :此BroadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者application user id为界的,而非进程为界(一个应用中可能含有多个进程)。
2、name :此BroadcastReceiver类名。
3、permission:如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收。
4、process:四大组件都具有这个属性。为组件指定单独的进程。不指定默认为app默认的进程。

    /**
     * 点击按钮发送自定义广播(隐式发送)
     */
   private fun send1() {
        val intent = Intent()
        intent.action = "sunny.day.custom.broadcast"
        sendBroadcast(intent)
    }

    /**
     * 点击按钮发送自定义广播(显式发送)
     */
    private fun send2() {
        val intent = Intent(this,MyBroadcastReceiver::class.java)
        intent.action = "sunny.day.custom.broadcast"
        sendBroadcast(intent)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/784535
推荐阅读
相关标签