AndroidAZ系列:四大组件之Broadcast(All,Face)
Git仓库地址
配套四维导图地址
AndroidAZ系列有以下目的:
- Android程序猿的面试(初级,中级,高级,资深),拿到满意的offer。
- 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 无序广播(普通广播)
普通广播是完全异步的,通过Context
的SendBroadcast()
函数来发送,消息传递的效率比较高,但所有的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.源码角度分析广播机制
参考链接
更多相关文章
- Nginx系列教程(四)| 一文带你读懂Nginx的动静分离
- Android(安卓)进程保活--1像素保活
- android Low Memory Killer介绍
- gradle自动修改android版本号的方法,取java静态变量重命名apk文件
- Android(安卓)OnLowMemory和OnTrimMemory
- Android中的BroadCastReceiver(广播接收者)————快速应用
- android 获取 USB 拔插广播消息
- android用户界面-提示信息Toast
- android 反射静态方法传值