0


Android 广播(Broadcast)

Android 广播Broadcast

1.小声嘀咕

UI和碎片的博客还没写,这周赶一下进度,可能这周就不写了,今天早上刚看了一下Broadcast,感觉不是特别难,写一下博客,加深一下印象

2.广播机制简介

Broadcast是android中的四大组件之一(其他的组件分别是:Activity,Content provider,Service),是在组件之间传播数据(Intent)的一种机制。广播的发送者和接收者事先是不需要知道对方的存在的。这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。

广播具有以下特性:

1.广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
2.广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
4.耗时的较长的工作最好放在服务中完成

3.接收系统广播

不要想的太难,举一个简单的例子吧:你如果手机要看番,那必须得上网吧,手机由没上网的状态到上网的状态,这种变化会发出的就是一种广播,我们想要接收这个广播就需要一个广播接收器,而获得广播接收器就需要自己注册,一共有2种注册方法,分别为动态注册静态注册(如果是在没办法理解广播的定义的话,你就把它当作一个全局监听器,用来实现不同组件的信息传递)

3.1动态注册

首先:动态注册是在代码中注册的,根据广播的一个特性广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
我们可以知道广播接收后一定要销毁,可是动态注册并不能自动销毁,所以,动态注册后一定要自己添加销毁的程序
说回正题:如何进行动态注册,很简单:

新创建一个类,让它继承BroadcastReceiver(BroadcastReceiver翻译过来就是广播),然后重写里面的OnReceive()方法

比如写一个监听网络变化的代码
在MainActivity中
添加代码
![在这里插入图片描述](https://img-blog.csdnimg.cn/746f98e9ba6541b8a824db27c35dd60d.png

我们先来看看效果

启动虚拟机
在这里插入图片描述
按住home键关闭网络
在这里插入图片描述
就会发现,Toast里面的话被成功输出

这里要注意一下:
创建一个IntentFilter的实例,给它添加一个action为android.net.conn.CONNECTIVITY_CHANGE(当网络发生变化,系统发出的广播就是这个 )(你想要监听什么,你就传入什么广播,可以看看这篇博客链接: 这个)

但是这有一点问题,你只知道网络改变了但不知道网络是开了还是关了
,我们可以这么改一下代码
在这里插入图片描述
然后再在AndroidManifest.xml文件中加上这句
在这里插入图片描述

,我们看一看效果
打开网络
在这里插入图片描述
关闭网络
在这里插入图片描述
这里有几点需要注意一下:

1.通过getSystemService()得到一个专门用于管理网络连接的系统服务类ConnectivityManager的实例,调用它的getActiveNetworkInfo()方法得到NetworkInfo的实例
,又用isAvailable()方法判断是否有网络
2.在AndroidManifest.xml文件中添加< uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE”/>是一个访问系统网络的权限,这样你的电脑就不会报错
3.NetworkInfo已经被弃用了,但是在本程序里面还是可以用

3.2静态注册

动态注册差不多是讲完了,现在我们来看一看静态注册
不同于动态注册,静态注册是在AndroidManifest.xml中注册的,并且,静态注册不需要手动取消注册
在这里插入图片描述
在这里插入图片描述

点击Finish
在这里插入图片描述
但是仅仅这样是不行的,我们得在AndroidManifest.xml文件中再加一句才能实现接收到开机广播
在这里插入图片描述
在这里插入图片描述
但是要注意一个事情,高版本的API(比如我用的API29,安卓8以上就用不了了)就已经没有静态注册了,你启动虚拟机,不会有Toast显示
如果仍然想用静态注册可以看看这篇博客链接: 安卓8.0如何静态注册

4.发送自定义广播

在说自定义广播之前,我们需要知道一个东西,Android的广播主要分为2种,一种是标准广播,一种是有序广播,其中标准广播发出后,所有广播接收器几乎同时接收到这条广播消息,并且不能被截断
有序广播同一时刻只有一个广播接收器会收到这条广播,并且可以被截断

4.1标准广播

我们先看看标准广播,
在刚才的代码下面,我们加一个按钮,作为广播的触发点,再用隐式Intent,将要发送的广播值传入,用
sendBroadcast()发送,点击一下按钮,你就会收到标准广播
这是第二版《第一行代码安卓》的方法,经实践,确定为做不到,安卓7以上就不兼容了

8.0后广播在AndroidManifest.xml中注册后发送intent是接收不到广播了,看了一下原因,好像是8.0为了管理系统和节约电量特别针对广播和服务发送intent的方式启动做出的改变,也就是说广播和服务不能随意收intent了,要对广播和服务更精确的指向,所以在创建intent的时候,我们需要指定我们的广播和服务的包名加类名,为的就是精确。

通过查阅网站后发现只需在建立intent后调用setComponent((new ComponentName(“包名”,“接收器类名”) )即可。
在AndroidManifest.xml中的静态注册也可以不指定action:

publicclassMainActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =findViewById(R.id.button);
        button.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(View v){Intent intent =newIntent();
                intent.setComponent(newComponentName("com.example.boardcast_receiver","com.example.boardcast_receiver.MyReceiver"));//参数为包名和类名,注意类名中要包括包名sendBroadcast(intent);}});}}

效果如下
在这里插入图片描述

注意一个事情如果intent.setComponent(new ComponentName(“com.example.boardcast_receiver”, “com.example.boardcast_receiver.MyReceiver”));的setComponent变红,无法运行按住ALT+ENTER键后选第一个就好了

4.2有序广播

前面的步骤和标准广播一样,注意有序广播的特点:
同一时刻只有一个广播接收器会收到这条广播,并且可以被截断

将有序广播种的sendBoardcast改成sendOrderedBroadcast(intent,null)

再设置广播接收器的优先级

<receiver
     android:name=".MyBroadcastReceiver"
     android:enabled="true"
     android:exported="true"><intent-filter android:priority="100"><action android:name="com.example.broadcasttest.MY_BROADCAST"/></intent-filter></receiver>

设置是否截断

publicclassMyBroadcastReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Context context,Intent intent){Toast.makeText(context,"收到了",Toast.LENGTH_SHORT).show();abortBroadcast();//加上这个方法就表示将广播截断}}

5.使用本地广播

发出的广播只能在应用程序的内部传递,并且广播接收器只能接收来自本应用程序的广播,使用之前要导v4包
修改MainActivity.java代码,建立intent时甚至不需要添加action参数:

publicclassMainActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button =findViewById(R.id.button);
        button.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(View v){Intent intent =newIntent();
                intent.setComponent(newComponentName("com.example.youyu4","com.example.youyu4.MyBroadcastReceiver"));//参数为包名和类名,注意类名中要包括包名sendBroadcast(intent);}});}}

本地广播的优势:
1.本地广播不会离开我们程序,不担心数据泄露
2.不会有安全漏洞,因为其他程序的广播不会发送到我们程序内部
3.更高效


本文转载自: https://blog.csdn.net/m0_61130325/article/details/126157019
版权归原作者 一碗海鸥拉面 所有, 如有侵权,请联系我们删除。

“Android 广播(Broadcast)”的评论:

还没有评论