四大组件之BroadcastReceiver

来源:互联网 发布:剑网3捏脸数据非法 编辑:程序博客网 时间:2024/04/19 15:34

广播接收者

概念

Android中的广播机制比我们日常生活中接触的广播更加灵活,Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样做的好处是我只接收我需要的广播,其他广播直接忽略。这些广播可以是来自于系统也可以是用户自定义的广播。

广播的类型:

标准广播:一套完全异步执行的广播,在广播发出去之后,所有的广播接收者几乎同时收到广播,接收者之间没有先后顺序的优先级之分。特点的效率高。

有序广播:同步执行的广播,同一时刻只能有一个广播接收者收到广播,当当前广播接收者执行完自己的逻辑之后,广播才会继续向下传递。优先级越高的广播接受者越先收到广播,同时先收到的广播接受者可以截断广播,阻止广播继续向下传递。
广播的优先级设定:-1000-1000
有些情况下,某些广播接受者必须要接收到广播(防止其他优先级高的接收者阻拦),可以设置为结果接收者(resultReceive):表示所有广播接收者都接收到广播之后,它才接收,并且一定会接收

定义方式:

定义一个类继承BroadcastReceiver,重写onReceive()方法即可,在该方法内部不要实现过多的逻辑或耗时操作,因为广播不能开启子线程。在清单文件中配置该类,指定接收的广播种类
广播是通过intent发送的,intent中会携带一个action,系统会在所有清单文件中寻找,看哪一个广播接收者的intent-filter和广播中的intent是匹配的,那么这个广播接收者就会收到这条广播
广播接收者所在进程即便没有启动,广播发送出来时,系统也会启动这个进程,然后把广播交给广播接收者
一个广播接收者可以接受多种广播,定义多个action即可

广播接收者注册:

清单文件注册:广播接收者永远生效,除非卸载应用,或者手动停止进程。
设置接收开启启动的广播

<receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver>
权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
使用代码注册:需要广播接收者生效时,注册它,不需要时,一定要反注册它,反注册之后,广播接收者就失效了。
private IntentFilter mIntentFilter;private MyReceiver mReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mIntentFilter = new IntentFilter();mIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");mReceiver = new MyReceiver();registerReceiver(mReceiver, mIntentFilter);}class myReceive extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {//实现逻辑}}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(mReceiver);}
特殊广播接收者,必须代码注册:屏幕开关、电量改变等
在程序中动态注册广播必须要在代码中取消注册,一般情况下在Activity的onDestory()方法中取消注册
静态注册广播需要在Mainfest中进行配置,可以收到程序在没有启动状态下的广播接收
当一条广播被发送出来时,系统是在所有清单文件中遍历,通过匹配意图过滤器找到能接收这条广播的广播接收者
发送自定义广播
public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//处理收到广播的逻辑}}<receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.example.broadcasttest.MY_BROADCAST"/></intent-filter></receiver>protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");sendBroadcast(intent);}});}

本地广播

使用LocalBroadcastManager对广播进行管理,并提供发送和注册广播接收器的方法。
本地广播无法通过静态方式注册,因为静态注册就是为了让程序在未启动的时候也能收到广播,而发生本地广播时,我们的程序是肯定启动了。
本地广播的优点:
可以明确地知道正在发送的广播不会离开我们的程序,因此不必担心机密数据泄露
其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全问题
发送本地广播比发送系统全局广播将会更加高效
public class MainActivity extends AppCompatActivity {    private IntentFilter intentFilter;    private LocalReceiver localReceiver;    private LocalBroadcastManager localBroadcastManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        localBroadcastManager = LocalBroadcastManager.getInstance(this); // 获取实例        Button button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");                localBroadcastManager.sendBroadcast(intent); // 发送本地广播            }        });        intentFilter = new IntentFilter();        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");        localReceiver = new LocalReceiver();        localBroadcastManager.registerReceiver(localReceiver, intentFilter); // 注册本地广播监听器    }    @Override    protected void onDestroy() {        super.onDestroy();        localBroadcastManager.unregisterReceiver(localReceiver);    }    class LocalReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();        }    }}