BroadcastReceiver简介
BroadcastReceiver翻译来就是广播接收器。实质上他就是一个全局的广播监听器。用于监听系统以及自定义的广播等,比如电池电量的改变。
BroadcastReceiver的使用步骤
- 创建BroadcastReceiver
- sendBroadCast()或sendOrderedBroadcast()
我们平时所给按钮设置的onClickListener()是程序级别的监听器,运行在程序所在的进程中没程退出时监听器也就关闭了。而BroadcastReceiver属于系统级别的监听器,注册方式有静态注册和动态注册两种方式。
BroadcastReceiver的两种注册使用方式
所谓动态注册就是在代码片中注册BroadcastReceiver,随着Activity、Service等生命周期的消亡而消亡。而静态注册是在AndroidManifest.xml文件中注册,这种方式生效在全局内,也就是应用退出了也会继续监听执行。也就是为什么平时你退出了qq,但是新消息来的时候还是会有提醒的原因。
····动态注册:
自定义BroadcastReceiver:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("test","action匹配为:"+intent.getAction()+",信息为:"+intent.getStringExtra("msg"));
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button open;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在onCreate()中注册BroadcastReceiver
//指定过滤规则
IntentFilter filter = new IntentFilter("com.alphathink.zdh");
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver,filter);
open = (Button) findViewById(R.id.button);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
intent.putExtra("msg","hello");
//发送广播
sendBroadcast(intent);
}
});
}
}
页面布局就一个按钮,就不贴了,点击后log为:
04-27 20:03:08.012 9302-9302/com.alphathink.myactivity V/test: action匹配为:com.alphathink.zdh,信息为:hello
····静态注册
静态注册就需要在AndroidManifest.xml中标签来声明:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alphathink.myactivity">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:allowTaskReparenting="true"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:theme="@style/Theme.AppCompat.Dialog" />
<!--静态注册BroadcastReceiver-->
<receiver android:name=".MyReceiver">
<!--定义过滤规则-->
<intent-filter>
<action android:name="com.alphathink.zdh"/>
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button open;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// //在onCreate()中注册BroadcastReceiver
// //指定过滤规则
// IntentFilter filter = new IntentFilter("com.alphathink.zdh");
// MyReceiver receiver = new MyReceiver();
// registerReceiver(receiver,filter);
open = (Button) findViewById(R.id.button);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
intent.putExtra("msg","hello");
//发送广播
sendBroadcast(intent);
}
});
}
}
运行后依然会和动态注册的结果一样:
04-27 20:14:20.562 12622-12622/com.alphathink.myactivity V/test: action匹配为:com.alphathink.zdh,信息为:hello
但是与之不同的是,我换一个app,同样执行如下方法,这个广播同样有效:
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
intent.putExtra("msg","hello");
//发送广播
sendBroadcast(intent);
BroadcastReceiver的生命周期和ANR
与Activity和Service不同的是,BroadcastReceiver的生命周期很短(和没有差不多),消息一经接收到就销毁掉了,从发送到接收一共才多少时间啊,其实想一下,广播理论上要求时效性比较强,所以不应该要耗费太多时间完成。如果BroadcastReceiver的onReceiver()不能在10s内执行完毕,就会出现ANR。
有序广播OederedBroadcast
上边所说的是普通广播,有序广播和普通广播的区别:
- 普通广播:完全异步,同一时刻可被其他所有符合过滤规则的广播接收到。无法终止。发送方式:sendBroadcast()
- 有序广播:按照规定的优先级依次传递,高优先级可修改数据、终止广播等操作。发送方式:sendOrderedBroadcast()
有序广播优先级为priority元素指定,范围为-1000~1000,终止广播调用abortBroadcast()即可。优先级高的接收到后可通过设置setResultExtras(Bundle)传给下一个接收者。通过Bundle bundle = getResultExtras(true)可获得传递数据。比如手机管家拦截垃圾信息就是通过设置自定义广播优先级高于系统的短信接收优先级,终止广播发送,所以短信系统收不到短信了。
第一个接收器:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("test","我是第一个广播接收器");
}
}
第二个接收器:
public class MyReceiver2 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.v("test","我是第二个广播接收器");
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button open;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在onCreate()中注册BroadcastReceiver
//指定过滤规则
IntentFilter filter = new IntentFilter("com.alphathink.zdh");
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver,filter);
//注册第二个广播
IntentFilter filter2 = new IntentFilter("com.alphathink.zdh");
MyReceiver2 receiver2 = new MyReceiver2();
registerReceiver(receiver2,filter2);
open = (Button) findViewById(R.id.button);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
//发送广播
sendBroadcast(intent);
}
});
}
}
运行结果:
04-27 21:45:45.326 12034-12034/com.alphathink.myactivity V/test: 我是第一个广播接收器
04-27 21:45:45.327 12034-12034/com.alphathink.myactivity V/test: 我是第二个广播接收器
设置优先级并终止测试:(只写修改的代码其他同上)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button open;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在onCreate()中注册BroadcastReceiver
//指定过滤规则
IntentFilter filter = new IntentFilter("com.alphathink.zdh");
//设置过滤优先级
filter.setPriority(99);
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver,filter);
//注册第二个广播
IntentFilter filter2 = new IntentFilter("com.alphathink.zdh");
filter2.setPriority(10);
MyReceiver2 receiver2 = new MyReceiver2();
registerReceiver(receiver2,filter2);
open = (Button) findViewById(R.id.button);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
//发送广播
sendOrderedBroadcast(intent,null);
}
});
}
}
第一个接收器:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("test","我是第一个广播接收器");
//终止广播
abortBroadcast();
}
}
运行结果:(第二个被拦截并终止了)
04-27 21:55:36.290 22643-22643/com.alphathink.myactivity V/test: 我是第一个广播接收器
拦截并修改数据后继续传递:
第一个接收器:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.v("test","我是第一个广播接收器");
//终止广播
Bundle bundle = new Bundle();
bundle.putString("key","hello,world");
setResultExtras(bundle);
}
}
第二个接收器:
public class MyReceiver2 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = getResultExtras(true);
String s = bundle.getString("key");
Log.v("test","我是第二个广播接收器"+"获得了数据"+s);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button open;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在onCreate()中注册BroadcastReceiver
//指定过滤规则
IntentFilter filter = new IntentFilter("com.alphathink.zdh");
//设置过滤优先级
filter.setPriority(1000);
MyReceiver receiver = new MyReceiver();
registerReceiver(receiver,filter);
//注册第二个广播
IntentFilter filter2 = new IntentFilter("com.alphathink.zdh");
filter2.setPriority(500);
MyReceiver2 receiver2 = new MyReceiver2();
registerReceiver(receiver2,filter2);
open = (Button) findViewById(R.id.button);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
//设置intent的过滤属性
intent.setAction("com.alphathink.zdh");
//发送广播
sendOrderedBroadcast(intent,null);
}
});
}
}
运行结果:
04-27 22:00:05.236 27450-27450/com.alphathink.myactivity V/test: 我是第一个广播接收器
04-27 22:00:05.239 27450-27450/com.alphathink.myactivity V/test: 我是第二个广播接收器获得了数据hello,world
关于过滤规则可以参考Activity中的规则,这个大同小异,地址:http://blog.youkuaiyun.com/z_dinghao/article/details/70500097