今天读了《第一行代码》并复习了一下广播机制,在这里做一个总结。
广播从类型上可以分为有序广播和标准广播两大类,从方法上分为静态注册的广播和动态注册的广播。在Android中,广播是跨进程的,因此在进程间传输数据时候,可能会泄露安全信息。因此在广播中还提供了本地广播(LocalBroadCastReceiver)来进行广播的安全管理。
因此,该文章就从静态注册广播、动态注册广播、自定义广播、本地广播四类来详细讲解BroadCastReceiver的用法。
动态注册广播
详细步骤:
1、写一个内部类继承自BroadCastReceiver类,并且实现onReceive方法。(广播接收器的实现)
class NetChangeBroadCast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this,NetWorkUtil.getWorkType(context),Toast.LENGTH_SHORT).show();
}
}
2、在Activity中定义一个监听网络变化的系统广播调用registerReceiver方法即可。
监听网络变化,因此要在AndroidMenifest.xml中添加网络权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
private void initBroadCast() {
intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
netChangeBroadCast = new NetChangeBroadCast();
registerReceiver(netChangeBroadCast,intentFilter);
}
3、当activity销毁的时候,在onDestroy中调用UnregisterReceiver方法。
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netChangeBroadCast);
}
动态注册广播,只有在程序启动之后才能够启动广播。
静态注册广播
详细步骤
1、创建一个BootBroadCastReceiver继承自BroadCastReceiver实现onReceive方法。
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"开机启动广播",Toast.LENGTH_SHORT).show();
}
}
2、在AndroidManifest.xml文件中注册广播
这个android.intent.action.BOOT_COMPLETED也是系统提供的广播,
即开机启动的广播。因此,要在AndroidMenifest中添加权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver android:name=".broadcast.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
intent-filter>
receiver>
application>
自定义广播
使用的是静态自定义广播的方式。
详细描述
1、 定义一个广播接收器MyBroadCastReceiver。
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"这是自定义的标准",Toast.LENGTH_SHORT).show();
}
}
2、 在AndroidMainfest中注册该广播。
<receiver android:name=".broadcast.MyBroadCastReceiver">
<intent-filter>
//这个是自定义的广播名称
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
intent-filter>
receiver>
3、 定义一个按钮来触发广播程序。
Intent mIntent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(mIntent);
广播是进程之间传递的,因此,新建一个BroadCastTest2项目,然后将BroadCastTest中的自定义广播引入到该项目中。点击“发送广播”按钮就会出现两条信息。
标准广播和有序广播
标准广播是完全异步执行的广播。该广播没有任何的顺序可言,因此效率比较高。也意味着它无法被截断。广播的工作流程如下:
有序广播是同步执行的,广播可以被中断。
下面是一个有趣的例子:
关于标准广播详细描述
1、创建两个工程,第一个工程BroadCastReceiverTest注册一个自定义的BroadCastReceiver广播命名为MyBroadCastReceiver,
代码如下:
MyBroadCastReceiver.java
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"这是自定义的标准",Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
AndroidMenifest.xml
<receiver android:name=".broadcast.MyBroadCastReceiver">
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
intent-filter>
receiver>
2、设置点击按钮,触发广播事件
mIntent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(mIntent);
3、创建第二个应用broadcasttest2,在AndroidMenifest中注册上一个应用所定义的广播com.example.broadcasttest.MY_BROADCAST。
<receiver android:name=".broadcast.AnotherBroadCastReceiver">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
intent-filter>
receiver>
运行两个程序,当点击第一个程序中的“发送广播”按钮时,两个应用程序会接收到相同的广播!这个就是标准广播的例子。
关于有序广播详细描述
有序广播创建广播的步骤基本不变,在方法实现上与标准广播稍有区别。
将以上例子改成有序广播的方式:
1、注册有序广播的方法。
使用sendOrderedBroadcast(mIntent,null)方法,第一个参数是Intent,第二个参数是设置权限,这里填入null。
mIntent = new Intent("com.example.broadcasttest.MY_BROADCAST");
//发送有序广播
sendOrderedBroadcast(mIntent,null);
2、在AndroidMenifest中可以添加广播级别
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
intent-filter>
3、在MyBroadCastReceiver(广播接收器)中设置拦截广播。
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"这是自定义的标准",Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
最后,发现点击“发送广播”按钮,第二个应用不会弹出消息。
本地广播
为了能够简单地解决广播的安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递, 并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。本地广播的用法并不复杂,主要就是使用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。
1、创建一个自定义的本地广播类
public class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"本地广播",Toast.LENGTH_SHORT).show();
}
}
2、在主activity中注册本地广播
private LocalBroadcastManager localBroadcastManager;
private LocalReceiver localReceiver;
localBroadcastManager = LocalBroadcastManager.getInstance(this);
mIntent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(mIntent);
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
3、退出activity时,销毁广播
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
我们发现,本地广播的使用和动态注册广播的方法基本相同,只是本地广播全都交给LocalBroadCastManager进行管理了。
以上代码全部上传在github上:https://github.com/hpulzl/name