将Android进行到底之广播(Broadcast)
Posted 时光剑客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将Android进行到底之广播(Broadcast)相关的知识,希望对你有一定的参考价值。
文章目录
前言
在VR的开发中,android的广播扮演着很重要的角色,因为我们的VR开发中显示的Launcher界面通常是使用Unity3d开发的,所以很多时候当我们想要在VR眼镜中,去调试我们的功能的时候。想象下,以前我们是直接在Android上显示,在Activity中写个Button就行了,但是遇到咱们到了VR眼镜中,要调试的时候,就不能直接在眼镜中让Unity3d的同事给你加个调试的按钮吧,人家也没那时间给你加
下图就是使用Unity3d渲染出来的Launcher 界面
就算人家给你加了,但是假如这时候操作的手柄还没就位你咋去点击VR眼镜里面的按钮呢?所以这时候广播的作用就体现出来了。我们可以通过发广播的形式去调试我们写的功能。广播不仅有这些作用还有好多妙用,让我们一起去看看吧。
一、广播的介绍
1.广播的概念
在Android中,广播是一种广泛应用在应用程序之间传输信息的机制,我们发送的广播内容是一个Intent,在这个Intent中,我们可以携带我们要发送的数据。举个例子,Android系统会在发生各种系统事件的时候发送广播,例如:系统启动了,电量改变了,USB设备插入拔出。设备充电时等等。不仅如此,我们还可以通过发送自定义的广播来通知其他应用,让他们做些事情。比如当一些新数据已经下载完了后,可以通过自定义广播通知其他应用。
2.广播的分类
系统会在发生各种系统事件的时候自动发送广播,比如当系统进入和退出飞行模式的时候。系统广播会被发送给所有统一接收相关事件的应用,广播消息本身会被封装在一个Intent对象中 ,该对象会有一个标识
(例如:android.intent.action.AIRPLANE_MODE)这个Intent可能还包含绑定其extra字段中的附加信息。如飞行模式intent包含布尔值extra来标识是否已经开启了飞行模式。
在App内监听这些广播也非常简单,咱们接着往下看
3.广播的使用
(1)接收广播
Android应用可以通过两种方式接收广播:分别是清单文件(AndroidManifest.xml)中声明的接收器(也叫静态注册),和上下文注册的接收器(也叫动态注册),咱们分别来看下两种注册方式。
1.在清单文件(AndroidManifest.xml)中声明的接收器
step1:创建一个类继承自BroadcastReceiver,并实现onReceive(Context,Intent)方法。
代码如下:
public class MyBroadcastReceiver
extends BroadcastReceiver
@Override
public void onReceive(Context context,
Intent intent)
String action = intent.getAction();
if(action.equls("android.intent.action.BOOT_COMPLETED")
//这样做是为了筛选出我们
//想要监听的广播,然后做咱们的处理逻辑
doSomeThings();
注意:广播时运行在主线程,所以不能在onReceive()方法中做耗时操作,否则可能会引起ANR
step2:在清单文件中声明广播接收器
<receiver android:name=".MyBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
</intent-filter>
</receiver>
声明广播接收器还可以使用上下文的方式,也就是咱们平常说的动态注册的方式,代码如下:
BroadcastReceiver br = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.android.intent.action.BOOT_COMPLETED);
this.registerReceiver(br, filter);
注意:只要注册的上下文有效,那么使用该上下文注册的接收器就会收到广播,例如,如果在Activity的上下文中注册,只要Activity没有被销毁,就会收到广播。如果是在Application的上下文中注册。只要应用还活着,没有被杀死,就可以接收到广播
step3:停止接收广播,当我们需要停止接收广播的时候,需要调用
unregisterReceiver(android.content.BroadcastReceiver)
方法停止接收广播,一般我们都会在上下文不在有效的时候注销广播接收器。比如:在Activity销毁时,在activity的onDestroy()回调中注销掉广播。
注意:我们注册和销毁接收器的位置需要特别小心。我们一般都是在Activity的onCreate()方法中注册广播,在onDestroy()中注销广播,但是假如你是在Activity的onResume()方法中注册的广播,则需要在onPause中注销广播,防止多次注册接收器
(2)发送广播
在前面的广播种类中我们提到了三种广播,所以发送广播的时候也分三种方式。分别是:
有序广播:sendOrderedBroadcast(Intent, String)
无序广播:sendBroadcast(Intent)
本地广播:LocalBroadcastManager.sendBroadcast
使用的方式很统一,除了调用的函数名不同,其他大概相同:代码如下:
Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data","Notice me senpai!");
sendBroadcast(intent);
注意: 广播消息封装在 Intent 对象中。Intent 的操作字符串必须提供应用的 Java 软件包名称语法,并唯一标识广播事件。我们可以使用 putExtra(String, Bundle) 向 intent 添加加其他信息。
二、广播的妙用
1.跨应用通信
这个最简单了,但是需要注意的是这里的跨应用通信指的可不是大数据量的通信哈,因为广播是挺耗性能的,所以尽量用来做些通知的事情。打个比方。广播相当于咱们在人群中大声喊出某条命令,确保所有人能听到,类似古代的传令兵,只能是喊有限的次数,可不能让人大声把兵法读给大家听吧。谁受得了呀。广播也是如此,咱们应该尽量让它做些短暂的命令通知就可以了
2.调试程序
广播调试程序可谓是一个字,爽。如何利用广播来调试程序呢?我们可以利用Android的调试工具adb来发送自定义的广播,在我们要调试的界面中写上广播接收器。然后接收到广播的时候执行咱们需要调试的内容就行了。
举个例子吧,假如咱们写了一个投屏的功能,使用广播的方式如何调试呢?以前的话咱们可能会写个按钮,点击的时候开始去投屏,这样很麻烦,在你自己的界面中还好,遇到我说的连接VR眼镜的时候,是不是就傻眼了。所以我们来看下利用广播如何做:
step1: 在要调试的类中去写上广播接收器:
private final static String ACTION_SAVE_DATA =
"action.save.data";
private final static String ACTION_START_CAST =
"action.start.cast";
private final BroadcastReceiver broadcastReceiver = new
BroadcastReceiver()
@Override
public void onReceive(Context context, Intent
intent)
String action = intent.getAction();
Log.d(TAG,"ACTION==============saveData==>>"
+ action);
if(action.equals(ACTION_SAVE_DATA))
Log.d(TAG,"save success====================>");
RtpReadAndPush.getInstance().saveData();
if(action.equals(ACTION_START_CAST))
Log.d(TAG,"ACTION === START CAST==>" +
action);
startCast(mCurrentLeLinkServiceInfo);
;
step2:在onCreate()方法中注册它
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cast);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_SAVE_DATA);
intentFilter.addAction(ACTION_START_CAST);
registerReceiver(broadcastReceiver,intentFilter);
step3:使用Adb发送自定义广播
adb shell am broadcast -a "action.start.cast"
step4:别忘了注销广播
@Override
protected void onDestroy()
super.onDestroy();
unregisterReceiver(broadcastReceiver);
3.配合service做容错处理
配合service做容错处理在咱们的前面也讲到了,其实很简单,因为service在配合AIDL做进程间通信的时候,通常都作为服务端,为客户端提供服务,假如服务端一直活着的情况下,客户端不出意外的话是百分百能够连接到服务端的,但是假如服务端意外死掉了,客户端这时候是不知道的,已经连接的客户端也不会重新去连接服务端,因为他们不知道服务端死掉了。所以这时候广播的作用就是告诉所有连接它的客户端,我发生异常重启了,你们重现连接下我再进行其他工作。
三、广播的注意事项
1.Android各版本的广播区别
随着 Android 平台的发展,它会不定期地更改系统广播的行为方式。如果应用以 Android 7.0(API 级别 24)或更高版本为目标平台,或者安装在搭载 Android 7.0 或更高版本的设备上,需要注意下面的版本变化:
Android 7.0
Android 7.0(API 级别 24)及更高版本不发送以下系统广播:
ACTION_NEW_PICTURE、ACTION_NEW_VIDEO
此外,以 Android 7.0 及更高版本为目标平台的应用必须使用 registerReceiver(BroadcastReceiver, IntentFilter) 注册 CONNECTIVITY_ACTION 广播。无法在清单中声明接收器。
Android 8.0
从 Android 8.0(API 级别 26)开始,系统对清单声明的接收器施加了额外的限制。如果应用以 Android 8.0 或更高版本为目标平台,那么对于大多数隐式广播(没有明确针对咱们应用的广播),不能使用清单来声明接收器。当用户正在活跃地使用的咱们开发的应用时,仍可使用动态注册的接收器。
Android 9
从 Android 9(API 级别 28)开始,NETWORK_STATE_CHANGED_ACTION 广播不再接收有关用户位置或个人身份数据的信息。此外,如果您的应用安装在搭载 Android 9 或更高版本的设备上,则通过 WLAN 接收的系统广播不包含 SSID、BSSID、连接信息或扫描结果。要获取这些信息,请调用 getConnectionInfo()。
2.不要滥用广播
一般来说,广播可作为跨应用和普通用户流之外的消息传递系统。但是,您必须小心,不要滥用在后台响应广播和运行作业的机会,因为这会导致系统变慢
总结
好了,以上就是今天的内容,篇幅有点长,希望能对正在阅读这篇文章的你带来收获,有疑问的可以在评论区一起交流。本人很热爱计算机,也很热爱我现在的职业。如果你和我志同道合,咱们一起共同交流,共同进步。
以上是关于将Android进行到底之广播(Broadcast)的主要内容,如果未能解决你的问题,请参考以下文章
android framework开发之广播broadcast源码分析-千里马
android framework开发之广播broadcast源码分析-千里马
android framework开发之广播broadcast源码分析2-千里马