广播这个组件不难,但是学完之后总会慢慢模糊,导致最后混淆,今天把感觉最容易搞混的知识点进行总结,希望能在下次搞混之后快速温习,温故而知新,总有一天理解的透透的!
反正在我工作的环境来说,由于我开发安卓相机,接受系统广播真的超级常用。所以这篇主要是从接收广播,处理广播说起。对于自定义广播发送以及处理,这里不做过多描述。
创建广播接收器
有人给你发东西,你肯定就要有个接收的载体嘛,根据发送不同的东西就会有不同处理的载体。其实融入现实来说,就好像在学校里面,学校发广播叫五班男同学去搬书,这时候可能全校都能听到,但是这时候只有五班同学做出了响应。每个班甚至每个人都是一个广播接收器,不同的广播会有不同的响应情况。
说了这么多,咱们来开始通过代码创建一下广播接收器吧。
其实安卓直接给我们封装了一个广播类。我们在创建自定义的广播接收器的时候只需要继承这个 类就可以拉,因为代码还是比较简单的,这里的代码直接复制了下面这个连接的网址,这个网址虽然在技术上可能比较旧的感觉,但是对于安卓入门还是绰绰有余的。大家有需要的基础知识可以来这个网站学习或者复习一下!
public class MyBRReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"网络状态发生改变~",Toast.LENGTH_SHORT).show();
}
}
这个例子是打算接收网络状态广播的,一般来说系统广播是不需要我们手动发送的,哈哈哈哈哈,这么说好像有点傻,系统广播当然不需要我们发送,也轮不到我们发送。我们要做的就需要注册这个广播接收器。
注册广播接收器
关于注册广播接收器分为两种注册,分别是动态注册、静态注册。
动态注册
在Java代码中指定intentFilter,然后添加不同的Action即可,想监听什么广播就写什么Action。另外动态注册的广播,一定要调用unRegisterReceiver然广播取消注册。
接下来上代码,大家一定要注意看我动态注册跟静态注册的区别,使用的广播接收器都是上文提到的MyBRReceiver进行演示。
myReceiver=new MyBRReceiver();
IntentFilter itFilter=new IntentFilter();
itFilter.addAction("android.net.com.CONNECTIVITY_CHANGE");
registerReceiver(myReceiver,itFilter);
可以看到这就完成了注册广播接收器的整个流程,是不是很简单,现在只要应用打开,当网络状态发生改变就会发生响应。 但是这种方式注册广播接收器有个弊端就是,在软件启动之后才能接收广播。为了解决这个问题,静态注册就此互补。
静态注册
动态注册需要程序启动后才能接收广播看,静态注册就弥补了这个短板,在AndroidManifest中制定<IntentReceiver>就可以在程序未启动的时候也能接收广播。
但是今天给的静态注册例子不会使用<IntentReceiver>,如若需要可以自行百度一下,我描述的只是静态注册的基本使用。
<receiver android:name="MyBRReceiver">
<intnt-filter>
<action android:name="android.net.com.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
总结:其实动态注册跟静态注册作用都是一样的,只是动态注册使用的是Java语言去注册,动态的声明。静态注册则是使用配置文件去进行注册,属于静态方式。
易混知识点
大家看我写的这两个实例代码可能会发现一个有点陌生的类——IntentFilter,这个类在我刚学习service的时候总是和intent给搞混,就一直在想他们之间到底有什么区别。
其实这两个类没有太大的关系,首先IntentFilter 在Java代码中使用就只限于广播动态注册的时候使用,在其他地方没有什么使用。而Intent用途非常广,Activity、Service都经常有他的身影。这边因为更多是自用,就直接写在同一篇帖子上。
Intent的易错点
首先Intent其实有点像一个中间媒介,不同组件之间的联系大部分都是通过Intent去完成的。Intent包括了主要六方面的信息,目标组件名、Extra、Flag、Category、Data、Action。
我认为以这种形式去看Intent的六个方面信息,可以更加清晰。
接下来我们来看看几个隐式Intent可能平时不是很注意的必备信息。
addFlag(int flags) 设置flag,决定目标组件的启动方式(不是隐式专属)
Action:该Activity可以执行的动作
Category:指定当前(Action)被执行的环境
具体隐式Intent用的最多的时候就是比如打开一个文件可以选择不同软件进行打开就是隐式的一种体现,他跟显式最大的区别就是不固定某个组件,只要符合action跟category的设置就会被调用到。
一般都是Manifest、Java代码结合进行使用。
Manifest.xml:
<intent-filter>
<action android:name="com.example.MY_ACTION"/>
<category android:name="com.example.MY_ACTION1(示例不准确)"/>
</intent-filter>
Java:
Intent intent=new Intent();
intent.setAction("com.example.MY_ACTION");
intent.addCategory("com.example.MY_ACTION1(示例不准确)");
可以看到只有<action>和<category>中的内容同时能够匹配Intent中的指定的action和category时,这个活动才能响应Intent。如果使用的是Default这种默认的category,在稍后调用startActivity的时候会自动将这个category添加到intent中。
何为显式与隐式
显式调用:Intent清楚的指出了被启动组件的信息,当调用了startActivity(intent)后,我们能明确的知道这次的任务式启动某个特定的组件。
隐式调用:跟显式恰好相反,没有特定的组件,而是通过Action、Category、Date来筛选合适的组件来打开。