Android四大组件-BroadcastReceiver

来源:互联网 发布:气象数据下载 编辑:程序博客网 时间:2024/04/29 20:09

一、简介

1.定义:广播接收器,即接收通过某一频道(Action)发送的广播,发送者可以是Activity和Service。

2、作用:
1) 监听系统的广播,并做相应的处理,如电量过低时需要保存相关数据,或发出通知警告用户
2)后台运行的服务,如经过耗时操作后,获取了网络数据,通过广播的方式通知用户。

3、常用的系统广播:注意:系统广播要严格按照官方API的说明方式使用
1)Intent.ACTION_BOOT_COMPLETED 系统开机启动完成
2)Intent.ACTION_SHUTDOWN 关机提醒广播
3)Intent.ACTION_BATTERY_LOW 低电量提醒广播
4)Intent.ACTION_BATTERY_CHANGED 电量发生变化广播(仅支持代码中注册)
5)Intent.ACTION_SCREEN_OFF 屏幕被关闭
6)Intent.ACTION_SCREEN_ON 屏幕已经被打开
7)Intent.ACTION_USER_PRESENT 屏幕解锁广播
8)Intent.ACTION_NEW_OUTGOING_CALL 拨号广播
9) TelephonyManager.ACTION_PHONE_STATE_CHANGED 来电时电话状态变化广播,如响玲、空置、挂断
10) Telephony.Sms.Intents.SMS_RECEIVED_ACTION 接收短信的广播

二、用法

1.步骤
1)创建类,继承BroadcastReceiver类
2) 重写onReceiver(Context,Intent)方法
3) 注册广播
-在AndroidManifest.xml中注册(全局)
-动态注册(局部):registerReceiver(BroadcastReceiver,IntentFilter)
4)发送广播
- Context.sendBroadcast(Intent)
- Context.sendBroadcast(Intent,String) 带有权限发送广播

三、广播的生命周期

1.继承后需要重写的唯一 一个方法onReceiver(Context,Intent)
2.在这个方法里可以做的事情
1)Toast
2)NotifyManager
3)Context.startActivity(Intent)
4)Context.sendBroadcast
5)Context.startService
6)IBinder BroadcastReciver.peekService(Context,Intent)
3.注意事项
1)广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
2)广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
3)最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
4)耗时的较长的工作最好放在服务中完成

四、广播的分类

1、标准广播:
是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播信息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被拦截的。
这里写图片描述

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

这里写图片描述

3、粘性广播
1)特点:普通的广播如果onReceive方法执行时间太长,超过10秒的时候系统会将这个广播置为可以干掉的candidate,一旦系统资源不够的时候,就会干掉这个广播而让它不执行
2)Intent会一直保留到广播事件结束,没有所谓的10秒限制
3)sendStickyBroadcast() 发送粘性的广播
4)android.Manifest.permission.BROADCAST_STICKY 声明权限

五、广播的安全性

1.发送广播时
1)发送带权限的广播sendBroadcast(Intent,permission)
2)指定接收广播的应用包名Intent.setPackage(“com.trainmobile.ss”)

2.在AndroidManifest.xml清单中配置

1)<permisson android:name="" /> 定义权限2)<uses-permission android:name=".."> 使用权限

3.注册接收广播时

1Context.registBroadcast(Intent,String),String为接收广播的权限2)<receiver androd:exported="false" ..>不接收外部应用的广播 

4.使用本地广播接收者LocalBroadcastManager
1)所在包:android.support.v4.content
2)LocalBroadcastManager.getInstance(Context)
3)registReceiver(BroadcastReceiver,IntentFilter)
4)sendBroadcast(Intent)
5)sendBroadcastSync(Intent intent)
6)unregisterReceiver(BroadcastReceiver receiver)

六、广播接收者的使用

1、案例1:接收电池电量改变时发送的广播
步骤:
接收系统广播(三大要素:广播的Action、接收广播的权限、广播中包含的数据)
1)自定义广播接收器类,继承BroadcastReceiver,并重写onReceiver()方法
2)注册广播接收器,同时通过IntentFilter声明广播接收器可以接收的广播频道(Action)
3)在广播接收的方法中,实现相关的操作(UI线程中执行的)

class MyReceiver extends BroadcastReceiver{        @Override        public void onReceive(Context context, Intent intent) {            //TODO 接收广播的方法--UI线程中执行的方法            //3.获取广播中的数据,并显示在UI控件上            //获取电量的等级信息(百分比)            String action = intent.getAction();            Log.i("--", action);            int level = 0;            if(action == Intent.ACTION_BATTERY_CHANGED){                level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);                textview.setText("当前电量:" + level + "%");                if(level < 10){                    //...                }            } else if(action == Intent.ACTION_BATTERY_LOW){                textview.setText("电量过低");            }else if(action == Intent.ACTION_POWER_CONNECTED){                textview.setText("电源连接");            }else if(action == Intent.ACTION_POWER_DISCONNECTED){                textview.setText("电源断开");                Intent infoIntent = new Intent(context, InfoActivity.class);                context.startActivity(infoIntent);            }        }    }
myReceiver = new MyReceiver();        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);        //增加可以接收的广播频道        filter.addAction(Intent.ACTION_BATTERY_LOW);        filter.addAction(Intent.ACTION_POWER_CONNECTED);//电源连接的广播        filter.addAction(Intent.ACTION_POWER_DISCONNECTED);//电源断开连接的广播        //2.注册广播接收器-接收系统点亮改变的广播        registerReceiver(myReceiver, filter);

2、案例2:开机自自动:实现很简单
1)自定义一个广播接收者

public class RootReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Intent mainIntent = new Intent(context, MainActivity.class);        context.startActivity(mainIntent);    }}

2)在清单文件中注册广播接收者

<receiver android:name="com.example.broadcastreceiver_2.RootReceiver" >            <intent-filter>                <action android:name="android.intent.action.BOOT_COMPLETED" />                <action android:name="android.intent.action.ACTION_USER_PRESENT" />                <action android:name="android.intent.action.ACTION_SCREEN_OFF" />                <action android:name="android.intent.action.ACTION_SCREEN_ON" />            </intent-filter>        </receiver>

3)关机开机试试看,实际开发中,一般的应用开机自启动都会被拒绝

3、案例3:有序广播的发送
1)定义三个自定义广播接收器
2)在清单文件中注册

<receiver android:name="com.beiing.broadcastreceiver_4.MyReceiver_1" >            <intent-filter>                <action android:name="com.beiing.broadcast.print" />            </intent-filter>        </receiver>        <receiver android:name="com.beiing.broadcastreceiver_4.MyReceiver_2" >            <intent-filter>                <action android:name="com.beiing.broadcast.print" />            </intent-filter>        </receiver>        <!-- android:exported="false" 不接受外部应用发送的广播 -->        <receiver android:name="com.beiing.broadcastreceiver_4.MyReceiver_3" >            <!-- 设置优先级 -1000~1000 -->            <intent-filter android:priority="100" >                <action android:name="com.beiing.broadcast.print" />            </intent-filter>        </receiver>

3)发送广播,看三个广播接收器的打印日志
4)测试:当发送标准广播时,sendBroadcast(。。),三个广播接收者会按注册的先后打印日志,然后把广播接收者3设置优先级高于1和2发送一个有序广播,sendOrderedBroadcast(。。),这样3会最先接收,然后1、2接收,如果这时候在3中调用切断广播的方法abortBroadcast();
广播将不会再往后发送。

最后说一点:之前讲到的handler可以进行子线程和主线程通信,现在通过发送广播和接收广播的方式也可以进行子线程和主线程通信。

七、源码下载

源码1
源码2
源码3

8 0
原创粉丝点击