Git仓库地址

配套四维导图地址

AndroidAZ系列有以下目的:

  1. Android程序猿的面试(初级,中级,高级,资深),拿到满意的offer。
  2. Android程序猿学习进阶。

标记说明:因为笔者是列出所有的Android知识点,因此面试不需要看那么多内容,如果是面试的知识点。笔者会加上标记Face,而如果不是面试的知识点,笔者会加上No标记,它是要学的东西;然后笔者将Android面试者或者面试者分为4个等级,初级A1,中级A2,高级A3,资深A4,如果这个知识点是所有等级的范围,那么笔者将会以all标记上。因此进阶路线就是A1->A2->A3->A4。也是面试者挑选的复习范围,假如你是中级程序员,那么你面试要看的内容就是包含A2&Face的标记。

  • All : 所有的Android工程师都看。

  • A1: 初级Android工程师。

  • A2: 中级Android工程师。

  • A3: 高级Android工程师。

  • A4: 资深Android工程师。

  • Face: 是面试的知识点。

  • No: 面试基本遇不到。

  • AndroidAZ系列:四大组件之Broadcast(All,Face)
    • 1.广播是什么
    • 2.广播的种类
      • 2.1 无序广播(普通广播)
      • 2.2 有序广播
      • 2.3 本地广播
      • 2.4 黏性广播(Android5.0 Api21失效)
    • 3.广播接收器
      • 3.1 静态注册
      • 3.2 动态注册
      • 3.3 静态注册和动态注册的区别
      • 3.4 系统发送的广播有哪些
    • 4.源码角度分析广播机制

1.广播是什么

在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。

2.广播的种类

2.1 无序广播(普通广播)

普通广播是完全异步的,通过ContextSendBroadcast()函数来发送,消息传递的效率比较高,但所有的receivers(接收器)的执行顺序不确定,缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播,直到没有与之匹配的的广播接收器为止。

使用方法:

首先继承BroadcastReceiver,然后需要重写onReceiver()方法,这样我们就实现了一个接收器。

public class MyBroadcastReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context, "hello", Toast.LENGTH_SHORT).show();    }}

2.2 有序广播

有序广播是一种同步执行的广播,在广播发出后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递. 有先后顺序,前面的广播能够截断正在传递的广播.

有序广播通过Context.sendOrderdBroadcast()来发送,所有的广播按照优先级顺序依次进行,广播接收器的 优先级通过receiver的intent-filter中的priority属性来设置,数组越大优先级越高(最大为最大数),当广播接收器结收到广播后可以使用setResult()函数来将结果传递给下一个接收器接收,然后通过getResult来获取上 一个接收器的返回的结果,并可以用abortBroadcast()函数来让系统丢弃该广播,该广播不在传递到别的广播接收器接收。

首先我们注册两个广播接收器

public class MyBroadcastReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        int i=1;        Toast.makeText(context, i+"", Toast.LENGTH_SHORT).show();        Bundle bundle=new Bundle();        bundle.putInt("I",i);        setResult(1,i+"",bundle);    }}
public class MyBroadcastReceiver2 extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        Bundle resultExtras = getResultExtras(true);        int i = resultExtras.getInt("I");        Toast.makeText(context, i+1+"", Toast.LENGTH_SHORT).show();    }}

并在androidManifest中注册并设置两个广播接收器的优先级

                                

然后发送一条有序广播,第二个参数是权限相关的字符串,可以传入null。

sendOrderedBroadcast(new Intent("hello"),null);

这时Toast分别弹出的是1和2,说明我们获取到了上一个广播接收器的结果,当然我们也能通过给优先级较高的接收器设置截断广播

abortBroadcast();

这样,之后的广播接收器都不会再接收到广播了。

2.3 本地广播

前面的两种广播都是全局广播,这样的广播可以被任意应用程序接收,并且我们也能接收到来自其他应用程序的广播,这样很容易引起安全问题,android为了解决这个问题引入了本地广播。,使用这个机制发送的广播只能在本应用程序内部进行传递,并且广播接收器也只能接收本应用程序的广播,这样所有的安全问题就不存在了。

首先先获取本地广播实例,并发送一条异步广播

localBroadcastManager=LocalBroadcastManager.getInstance(this);localBroadcastManager.sendBroadcast(new Intent("hello1"));

然后通过本地广播接收者接收本地广播

private BroadcastReceiver register=new BroadcastReceiver() {    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context, "hello1", Toast.LENGTH_SHORT).show();    }};localBroadcastManager.registerReceiver(register,new IntentFilter("hello1"));

最后在onDestory中注销本地广播接收者,避免oom。

@Overrideprotected void onDestroy() {    super.onDestroy();    unregisterReceiver(register);}

2.4 黏性广播(Android5.0 Api21失效)

sticky广播通过Context。sendStickyBroadcast()函数来发送,用此函数发送的广播会一直滞留,当有与之匹配的 广播接收器接被注册后,该广播接收器就会接收到广播,当然sticky广播需要下面权限。

sticky只保留最后一条广播,并且一直保留下去,这样即使有广播接收器处理了该广播,当有再与之匹配的广播接收器接收时,此广播任会被接收,如果你只想处理一次广播,可以通过removeStickyBroadcast()函数实现。

3.广播接收器

3.1 静态注册

四大组件都需要在Androidmanifest中进行注册

                

3.2 动态注册

registerReceiver(new MyBroadcastReceiver(),new IntentFilter("hello"));

如果是动态注册的,别忘了在onDestory()中注销广播

@Overrideprotected void onDestroy() {    super.onDestroy();    unregisterReceiver(new MyBroadcastReceiver());}

现在我们能给发送一条广播了

sendBroadcast(new Intent("hello"));

当我们发送一条广播是会弹出一条Toast,说明广播接收器接收到了。

3.3 静态注册和动态注册的区别

  • 动态注册受Activity的生命周期影响,当Activity销毁的时候,广播就失效了.而静态注册的广播即使Activity销毁了,仍然可以收到广播,即使杀死进程,仍然可以收到广播

  • 动态注册的广播永远要快于静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级多低.

3.4 系统发送的广播有哪些

常见系统广播

打电话

                   

接电话

                 

开机

                

安装包相关

                                                //注意这个是必须的                

接收短信

                
public class BootReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Object[] object = (Object[]) intent.getExtras().get("pdus");        for (Object obj : object) {            SmsMessage ss = SmsMessage.createFromPdu((byte[]) obj);            String messageBody = ss.getMessageBody();            String originatingAddress = ss.getDisplayOriginatingAddress();            System.out.println(messageBody+":"+originatingAddress);        }    }}

屏幕的锁屏和解锁(只能动态注册)

receiver = new BootReceiver();IntentFilter filter = new IntentFilter();filter.addAction("android.intent.action.SCREEN_OFF");filter.addAction("android.intent.action.SCREEN_ON");registerReceiver(receiver, filter);unregisterReceiver(receiver);

下面5个系统广播只能动态注册而不支持静态注册

android.intent.action.SCREEN_ONandroid.intent.action.SCREEN_OFFandroid.intent.action.BATTERY_CHANGEDandroid.intent.action.CONFIGURATION_CHANGEDandroid.intent.action.TIME_TICK

4.源码角度分析广播机制

参考链接

更多相关文章

  1. Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
  2. Android(安卓)进程保活--1像素保活
  3. android Low Memory Killer介绍
  4. gradle自动修改android版本号的方法,取java静态变量重命名apk文件
  5. Android(安卓)OnLowMemory和OnTrimMemory
  6. Android中的BroadCastReceiver(广播接收者)————快速应用
  7. android 获取 USB 拔插广播消息
  8. android用户界面-提示信息Toast
  9. android 反射静态方法传值

随机推荐

  1. Android属性动画,看完这篇够用了吧
  2. Android(安卓)桌面组件【app widget】 进
  3. Android(安卓)多主题切换 (theme + style
  4. Android传感器概述(二)
  5. Android(安卓)-- Parcelable 序列化操作
  6. Android(安卓)UI编程进阶——使用Surface
  7. Android学习小Demo(5)结合Matrix跟Porperty
  8. Android全屏截图的方法,返回Bitmap并且保
  9. Data Binding Guide——google官方文档翻
  10. Android(安卓)内存优化篇 - 使用profile