Android学习笔记----广播接收者

/*********************************************************************************************************************/

此博客原本是本人学习Android过程中自己所做的学习笔记,在此分享出来供大家学习,因为之前只是个人笔记仅供自己回顾复习,所以笔记里可能借鉴了其他人的一些资料,整理博客的过程中已经忘了资料的来源,所以未做标注,望被鄙人借鉴了资料的原创者们见谅。

/*********************************************************************************************************************/

广播分类

Android 中的广播主要可以分为两种类型, 标准广播和有序广播

标准广播( Normal broadcasts)  是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。标准广播的工作流程:


注:标准广播也叫无序广播,无序广播不能设置优先级,没有abortbroadcast()方法。

有序广播( Ordered broadcasts) 则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先  收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。有序广播的工作流程:

注:有序广播可以设置优先级, abortbroadcast() 方法

/*********************************************************************************************************************/

接收系统广播

/*********************************************************************************************************************/

创建广播接收器

新建一个类,让它继承自 BroadcastReceiver,并重写父类的 onReceive()方法就行了。这样当有广播到来时, onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。

class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectionManager = (ConnectivityManager)        . getSystemService(Context.CONNECTIVITY_SERVICE); //获取网络状态管理器
        NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo(); //获取网络状态信息
        if (networkInfo != null && networkInfo.isAvailable()) {
            Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show(); 
        } else {
            Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show(); 
        }
    }
}

注意:

权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

注册广播接收器

广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种:
代码中注册和在 AndroidManifest.xml 中注册,其中前者也被称为动态注册,后者也被称为静态注册。

动态注册广播接收器

private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;

intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); //添加广播接收器想要接收的广播,此处表示接收网络状态变化的广播
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);

注意:
动态注册的广播接收器一定都要取消注册才行,这里我们是在 onDestroy()方法中通过调用 unregisterReceiver(networkChangeReceiver)方法来实现的。

静态注册广播接收器

动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的,静态注册可以让程序在未启动的情况下就能接收到广播一旦应用程序被部署到手机, 广播接收者就会生效。


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
……
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />//访问网络状态需要的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />//监听系统开机广播需要的权限
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    ……
    <receiver android:name=".BootCompleteReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />//标记该广播接收器接收系统发出的开机广播
        </intent-filter>
    </receiver>

</application>
</manifest>

注:BootCompleteReceiver是一个自定义的广播接收器,作用接收开机广播,然后弹出吐司,显示开机启动了

注意:不要在 onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为广播接收器是运行在主线程中的,而且在广播接收器中是不允许开启线程的(因为广播接收器的生命周期非常短,开启线程的话,可能当广播接收器被回收的时候,而开启的线程还没有运行完,导致出错),当 onReceive()方法运行了较长时间而没有结束时,程序就会报ANR异常。因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。 

/*********************************************************************************************************************/

发送自定义广播

/*********************************************************************************************************************/


发送标准广播

//自定义广播接收器,接收发送的自定义广播
public class MyBroadcastReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(context, "received in MyBroadcastReceiver",  Toast.LENGTH_SHORT).show(); 
            }
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
……
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    ……
    <receiver android:name=".MyBroadcastReceiver">//注册自定义的广播接收器
        <intent-filter>
            <action android:name="com.example.broadcasttest. MY_BROADCAST"/>//标注该广播接收器接收的广播类型
            <category android:name="android.intent.category.DEFAULT"/>//注意这个一定要加上不然的话会接收不到广播  
          </intent-filter>
    </receiver>

</application>
</manifest>

代码中注册

        MyBroadcastReceiver rec = new MyBroadcastReceiver();
        IntentFilter intentFileter = new IntentFilter();
        intentFileter.addAction("com.example.broadcasttest. MY_BROADCAST");
         intentFileter.addCategory(Intent.CATEGORY_DEFAULT); //一定要加上addCategory(Intent.CATEGORY_DEFAULT)不然会接收不到自定义的广播
        registerReceiver(rec,intentFileter);


//发送自定义广播
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST"); 
sendBroadcast(intent);

注:应用程序发出的广播是可以被其他的应用程序接收到的。
           记得动态注册的广播接收者都要取消注册

发送有序广播
 
只需要将发送标准广播的代码改成sendOrderedBroadcast(intent,null)即可

注:第二个参数是一个与权限相关的字符串,这里传入 null 就行了

有序广播可以在AndroidManifest.xml 文件中设置广播的优先级(通过设置 android:priority属性)或者在代码中通过setPriority()方法设置,高优先级的广播接收器先接收到广播,可以选择在高优先级的广播接收器中,对接收到的广播进行中断(调用abortbroadcast()方法)或者对广播的数据进行修改,让低优先级的广播接收器接收到经过修改后的数据。


发送本地广播

如果只想让本应用接收到自己发送的广播,不想让手机上的其他应用接收到广播,可以利用”本地广播“。本地广播主要就是使用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。

private IntentFilter intentFilter;

private LocalBroadcastManager localBroadcastManager;

private MyBroadcastReceiver myBroadcastReceiver;

localBroadcastManager = LocalBroadcastManager.getInstance(this);// 获取实例广播
 
myBroadcastReceiver 
= new  
MyBroadcastReceiver 
();

intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");

localBroadcastManager.registerReceiver(localReceiver, intentFilter); 
// 注册本地广播监听器


Intent intent = new Intent("
com.example.broadcasttest.LOCAL_BROADCAST
");
localBroadcastManager.sendBroadcast(intent); // 发送本地广播

注:本地广播是无法通过静态注册的方式来接收的。其实这也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能收到广播,而发送本地广播时,我们的程序肯定是已经启动了,因此也完全不需要使用静态注册的功能。

使用本地广播的几点优势 :
1. 可以明确地知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄 漏的问题。
2. 其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐 患。
3. 发送本地广播比起发送系统全局广播将会更加高效。






此博客原本是本人学习Android过程中自己所做的学习笔记,在此分享出来供大家学习,因为之前只是个人笔记仅供自己回顾复习,所以笔记里可能借鉴了其他人的一些资料,整理博客的过程中已经忘了资料的来源,所以未做标注,忘被鄙人借鉴了资料的原创者们见谅。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值