加入收藏 | 设为首页 | 会员中心 | 我要投稿 52刷机网 (https://www.52shuaji.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 安卓频道 > 安卓资讯 > 正文

细解 Android 中的广播机制

发布时间:2021-12-07 12:43:09 所属栏目:安卓资讯 来源:互联网
导读:详解 Android 中的广播机制 Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接受自己所关心的广播内容,这些广播内容可能是来自于系统,也可能是来自于其他应用程序的. 作者:Android开发编程来源:Android开发编程|2021-11-24
详解 Android 中的广播机制
Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接受自己所关心的广播内容,这些广播内容可能是来自于系统,也可能是来自于其他应用程序的.
 
作者:Android开发编程来源:Android开发编程|2021-11-24 08:33 收藏  分享
 
前言
Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接受自己所关心的广播内容,这些广播内容可能是来自于系统,也可能是来自于其他应用程序的;
 
Android 提供了一整套的 API,允许应用程序自由地发送和接受广播
 
今天我们就来详细介绍下
 
一. 广播介绍
 
1、标准广播
这是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。接收器不能对收到的广播做任何处理,也不能截断广播继续传播;
该种类的广播用sendBroadcast发送;
2、有序广播
这是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递;
所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了;
该种类的广播用sendOrderedBroadcast发送;
3、粘性广播
粘性广播的特点是Intent会一直保留到广播事件结束,而这种广播也没有所谓的10秒限制,10秒限制是指普通的广播如果onReceive方法执行时间太长,超过10秒的时候系统会将这个广播置为可以被干掉的‘候选人’,一旦系统资源不够的时候,就会干掉这个广播而让它不执行。该广播用sendStickyBroadcast发送;
在Android5.0 & API 21中已经失效,所以不建议使用;
二、广播详解
Android 内置了很多系统级别的广播,我们可以在应用中通过监听这些广播来得到各种系统的状态信息。比如手机开机后会发送一条广播,电池的电量发生变化会发出一条广播,时间或时区发生改变也会发出一条广播等等;
 
注册广播方式一般有两种:
 
动态注册在代码中注册;
 
静态注册在 AndroidManifest.xml 中注册
 
1、静态注册
一般为常驻广播,在AndroidManifest.xml里通过标签声明
 
<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>
 
intent过滤器里指定的是接收器订阅的action;
 
2、动态注册
非常驻广播,在使用时注册,用完及时销毁;
 
BroadcastReceiver br = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    this.registerReceiver(br, filter);
记得及时注销,以免内存泄漏;
 
@Override
 protected void onDestroy() {
     super.onDestroy();
     unregisterReceiver(receiver);
 }
3、自定义广播
注册广播
 
 
 <receiver
            android:name=".test.MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.test.test" />
            </intent-filter>
  </receiver>
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"发送标准广播",Toast.LENGTH_LONG).show();
    }
}
  Intent intent = new Intent("com.test.test");
                 sendBroadcast(intent);
//发送有序广播
 Intent intent = new Intent("com.test.test");
                 sendOrderedBroadcast(intent,null);  
4、本地广播
我们发送和接受的广播全部属于系统全局广播,即发出的广播可以被其它任何应用程序接收到,并且我们也可以接受来自于其它任何应用程序的广播;
 
为了解决广播安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能在应用程序内部进行传递,并且广播接受器也只能接受来自本应用程序发出的广播,这样所有的安全性问题就都不存在了;
 
初始化广播:
 
private LocalBroadcastManager localBroadcastManager;
   private void init() {
       //获取实例
       localBroadcastManager = LocalBroadcastManager.getInstance(this);
       IntentFilter intentFilter = new IntentFilter();
       intentFilter.addAction("om.test.LOCAL_BROADCAST");
       LocalReceiver localReceiver = new LocalReceiver();
       localBroadcastManager.registerReceiver(localReceiver, intentFilter);
   }
Intent intent = new Intent("om.test.LOCAL_BROADCAST");
       localBroadcastManager.sendBroadcast(intent);
定义
   private class LocalReceiver extends BroadcastReceiver {
       @Override
       public void onReceive(Context context, Intent intent) {
           Toast.makeText(context, "本地广播.....", Toast.LENGTH_LONG).show();
       }
   }
优点:
 
可以明确知道正在发送的广播不会离开我们的程序,因此不必担心机密数据泄露:
其它的程序无法将广播发送到我们程序内部,因此不需要担心会有安全漏洞问题:
发送本地广播比发送系统全局广播更加高效:
5、带权限的标准广播
发广播
 
当调用sendBroadcast(Intent, String)或sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)时,可以指定权限参数;
 
sendBroadcast(new Intent("com.test"),
              Manifest.permission.SEND_SMS);
要想接收这个广播,那么这个接收的app必须申请该权限
 
<uses-permission android:name="android.permission.SEND_SMS"/>
 
接收广播
如果在注册广播接收器时指定了权限参数(使用registerReceiver(BroadcastReceiver,IntentFilter,String,Handler)或清单文件中的里),则只有在清单文件中使用请求权限的广播发送者才可以将Intent发送给接收者;
 
在清单文件中声明:
 
<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.SEND_SMS">
    <intent-filter>
        <action android:name="com.test"/>
    </intent-filter>
</receiver>
 
在注册的时候声明:
 
IntentFilter filter = new IntentFilter("com.test);
registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null );
要给它发消息,那广播发送的app就必须得申请获得相应的权限才行:
 
<uses-permission android:name="android.permission.SEND_SMS"/>
 
总结
动态注册广播不是常驻型广播,也就是说广播跟随Activity的生命周期。注意在Activity结束前,移除广播接收器;
 
静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行;
 
当广播为有序广播时:优先级高的先接收(不分静态和动态)。同优先级的广播接收器,动态优先于静态;
 
同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的;
 
当广播为默认广播时:无视优先级,动态广播接收器优先于静态广播接收器。同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后册的。

(编辑:52刷机网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读