Android四大组件之BroadcastReceiver详细解析

什么是BroadcastReceiver?

BroadcastReceiver作为Android四大组件之一,在实际开发中也发挥着重要的作用,广播机制在Android程序通信中至关重要,广播其实与我们现实生活中的电台很相似,电台在某个频道上发送它的内容,那么只要有在收听这个频道的人都会收到这些内容。在Android中,广播也同样分为两个角色:广播发送者广播接收者

BroadcastReceiver的应用场景

1.在一个应用中,我们的Activity与Service的通信就需要用到广播来作为中介,比如Service在后台进行着下载任务,当下载成功后,需要通知Activity,这个时候就可以用到广播了。

2.在Android中,有时候两个app之间需要进行通信,比如你再一个app里面点击某个按钮时需要通知另外一个app的启动,这个时候就需要在点击按钮时发送一个广播,而另外那个app就是作为广播接收者。

3.另外一种应用场景是由系统来发出广播,你的应用充当广播接收者的角色,比如你需要在手机断网时在你的App中马上做出相应提示,在手机启动时让你的app收到系统发来的广播:“手机启动了哦!”,然后你的应用就会马上进行相应的操作,比如开机自启动等等。

广播最大的特点就是:发送方与接收方是解耦的,即发送方虽然发送了广播,但它并不关系接收方到底收到了没有,或者接受方拿到广播之后要干嘛,而接收方只需要注册有这个广播,就会在收到相同类型的广播消息时做出相应。而且广播可以是一个发送者,多个接收者。

如何使用广播?

前面说过了,广播是需要注册的,也就是需要注册一个广播接收者,在Android中,广播注册分为两种方式:

1.静态注册广播【在AndroidManifest.xml中注册BroadcastReceiver】

2.动态注册广播【通过代码注册BroadcastReceiver】

静态方式注册自定义广播

1.发送广播,这里以Activity为例,在Activity的onCreate中发送一个广播

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Intent intent = new Intent();
		//这条广播的标志
		intent.setAction("broadcast_test");
		//携带数据
		intent.putExtra("msg", "这是自定义静态广播消息");
		//发送广播
		sendBroadcast(intent);

	}
}

关键在于sendBroadcast这个方法,通过这个方法将广播的intent发出,可以通过intent携带数据

注意:setAction表示为intent设置上一个action,相当于这个广播的一个标志,只有与这个标志匹配的广播接收者才会接收到这个消息。

2.创建广播接收者,新建一个类继承于BroadCastReceiver,实现其中的onReceive方法

public class MyReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub

		//获得广播中的数据
		String msg = intent.getStringExtra("msg");
		//模拟响应
		Toast.makeText(context, msg, 1000).show();

	}

}

在onReceive方法中进行接收到广播后做出的各种响应操作,onReceive方法有两个参数:context表示发送广播的那个地方,一个就是广播所携带的intent咯,也就是上一步中的sendBroadcast中发送过来的intent。所以自然而然就能够从中拿到相应的数据。

3.在AndroidManifest.xml中注册我们定义好的广播

注意:action标签的name一定要与第一步中intent所设置的action一致,才能收到广播

运行

动态方式注册自定义广播

1.发送广播,这里以Activity为例,在Activity的onCreate中发送一个广播

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		//动态注册receiver的Intent过滤器和action
		IntentFilter filter = new IntentFilter();
		filter.addAction("broadcast_test");
		registerReceiver(new MyReceiver(), filter);

		Intent intent = new Intent();
		//这条广播的标志
		intent.setAction("broadcast_test");
		//携带数据
		intent.putExtra("msg", "这是自定义动态广播消息");
		//发送广播
		sendBroadcast(intent);

	}
}

可以看到,这里与静态的不同就在于多了IntentFileter的生成和receiver的注册,相当于将在xml中receiver的注册变成用代码来进行注册

2.同样需要有广播接收者,新建一个类继承于BroadCastReceiver,实现其中的onReceive方法

public class MyReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub

		//获得广播中的数据
		String msg = intent.getStringExtra("msg");
		//模拟响应
		Toast.makeText(context, msg, 1000).show();

	}

}

运行

上面演示了如何静态和动态发送自定义广播,下面通过手机飞行模式的开关来演示如何静态和动态接收来自系统的广播

静态接收系统广播

1.新建一个广播接收者,用来接收特定的系统广播

public class MyReceiver extends BroadcastReceiver{

	//用来作为标志,判断是开启还是关闭
	private static int count = 0;

	//如果是飞行模式状态变化的广播,就执行操作
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//每改变一次飞行状态,count就+1
		count++;
		switch (count%2) {
		//如果余数为1,说明count是奇数,也就是操作--->开启飞行模式
		case 1:
			Toast.makeText(context, "开启飞行模式", 1000).show();
			break;
		//如果余数为0,说明count是偶数,也就是操作--->关闭飞行模式
		case 0:
			Toast.makeText(context, "关闭飞行模式", 1000).show();
			break;
		}
	}
}

2.在AndroidManifest中注册该广播接收者

<receiver android:name=".MyReceiver">
	<intent-filter>
                <action android:name="android.intent.action.AIRPLANE_MODE"/>
        </intent-filter>
</receiver>

注意这里用的action是android.intent.action.AIRPLANE_MODE,这是由系统提供的当手机飞行状态改变时发出的广播,正是因为此处将MyReceiver注册为接收指定的系统广播,才会在onReceive中接收到这个广播

动态接收系统广播

1.新建一个广播接收者,与静态的基本一致

public class MyReceiver extends BroadcastReceiver{

	//用来作为标志,判断是开启还是关闭
	private static int count = 0;

	//如果是飞行模式状态变化的广播,就执行操作
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//每改变一次飞行状态,count就+1
		count++;
		switch (count%2) {
		//如果余数为1,说明count是奇数,也就是操作--->开启飞行模式
		case 1:
			Toast.makeText(context, "开启飞行模式", 1000).show();
			break;
		//如果余数为0,说明count是偶数,也就是操作--->关闭飞行模式
		case 0:
			Toast.makeText(context, "关闭飞行模式", 1000).show();
			break;
		}
	}
}

2.在Activity中对它进行注册

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		IntentFilter filter = new IntentFilter();
		//这里将飞行模式改变的Action添加到过滤器中
		filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
		registerReceiver(new MyReceiver(), filter);
	}
}

运行

如何取消注册广播?

在上面的动态注册自定义广播的例子中,如果你尝试将当前应用程序kill掉,就会发现Logcat报出如下错误:

从报错信息中可以看出,是由于我们是动态注册的自定义广播,所以在Activity被销毁时,广播接收者将不再接收相应的广播,系统要求必须注销该广播

解决方法很简单,只需要在Activity的onDestroy方法中,调用unregisterReceiver(myreceiver);就可以在Activity退出时注销广播:

@Override
protected void onDestroy() {
	// TODO Auto-generated method stub
	super.onDestroy();
	unregisterReceiver(myreceiver);
}

有序广播

上面所演示的广播都是通过sendBroadcast发送出去的,是无序的广播,有时候广播接收者是有多个的,如果我们需要将它们设定一定的优先级,就需要通过sendOrderedBroadcast()来发送有序广播

下面通过自定义三个广播接收者和一个广播发送者,演示如何使用有序广播:

1.创建三个广播接收者

有序广播

上面所演示的广播都是通过sendBroadcast发送出去的,是无序的广播,有时候广播接收者是有多个的,如果我们需要将它们设定一定的优先级,就需要通过sendOrderedBroadcast()来发送有序广播

下面通过自定义三个广播接收者和一个广播发送者,演示如何使用有序广播:

1.创建三个广播接收者

MyFirstReceiver.java:

public class MyFirstReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		String msg = intent.getStringExtra("msg");
		Log.d("MyFirstReceiver", msg);
		//将数据传输给下一个广播接收者
		setResultData("This is the Second Msg From MyFirstReceiver");
	}

}

MySecondReceiver.java:

public class MySecondReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//获得上一个广播接收者传过来的数据
		String msg = getResultData();
		Log.d("MySecondReceiver", msg);
		//将数据传输给下一个广播接收者
		setResultData("This is the Third Msg From MySecondReceiver");
	}

}

MyThirdReceiver.java:

public class MyThirdReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		//获得上一个广播接收者传过来的数据
		String msg = getResultData();
		Log.d("MyThirdReceiver", msg);
	}

}

2.在AndroidManifest.xml中注册三个广播接收者:

<receiver
           android:name=".MyFirstReceiver">
           <intent-filter android:priority="300">
                <action android:name="OrderBroadcast"/>
           </intent-filter>
</receiver>

<receiver
           android:name=".MySecondReceiver">
           <intent-filter android:priority="200">
                <action android:name="OrderBroadcast"/>
           </intent-filter>
</receiver>

<receiver
           android:name=".MyThirdReceiver">
           <intent-filter android:priority="100">
                <action android:name="OrderBroadcast"/>
           </intent-filter>
</receiver>

注意到这里每个接收者都多加了一个属性:priority,这个属性表示有序广播中的优先级,值越高表示优先级越高,那么当广播发出时,优先级最高的便会第一个接收到广播并拦截下来。然后才会继续往优先级低的传递下去。

3.发送有序广播

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Intent intent = new Intent("OrderBroadcast");
		intent.putExtra("msg", "This is the First Msg From Activity");
		sendOrderedBroadcast(intent, null);
	}

}

运行,查看Logcat打印结果:

局部广播

上面的有序广播和无序广播都是属于全局广播,也就是当发出这个广播,整个系统都有机会接收到该广播,但有时候出于安全性问题的考虑,Android还提供了局部广播,这种广播只有在同一个App内的广播接收器才能收到,其它应用不会接收到。

局部广播的使用:

public class MainActivity extends Activity {

	private MyReceiver receiver = new MyReceiver();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);

		IntentFilter filter = new IntentFilter();
		filter.addAction("broadcasttest");
		//注册局部广播
		manager.registerReceiver(receiver , filter);

		Intent intent = new Intent();
		intent.setAction("broadcasttest");
		//发送广播
		manager.sendBroadcast(intent);

	}

}

BroadcastReceiver的生命周期

【三部曲】调用广播--->执行onReceive()--->onReceive方法return之后即结束该广播

该注意的点

Android中规定了BroadCastReceiver不能处理复杂长时间的逻辑操作,如果在onReceive方法在10s内没法执行完毕,则系统会视之为未响应状态,可能会报ANR错误。可以将这些耗时操作放在Service中开辟子线程去执行。

至此,对于BroadcastReceiver在Android中的使用已经基本了解,我会在以后的博文中用实战demo来演示广播在开发中的应用!整理不易,如果你觉得本文对你有所帮助,请点个赞,如果有哪些地方存在不足,还望指出,共同探讨。

时间: 2024-07-29 21:35:55

Android四大组件之BroadcastReceiver详细解析的相关文章

Android 四大组件 (三) BroadcastReceiver 介绍

一. BroadcastReceiver 使用场景 Broadcast主要是用作消息通信(专业术语叫IPC),Android的IPC基本都是binder来实现,那么这里的BroadcastReceiver其实也是对binder的一个封装,方便上层调用.开发过程中遇到的单进程多线程通信的场景比较多,所以这种情况下使用Broadcast并不是最佳选择,很多人会自己实现一套 Observer 或者使用EventBus等第三方库来完成该功能,不可否认,他们在这种场合下不论是效率还是灵活性方面都更具优势.

Android四大组件之~~BroadcastReceiver

声明:转载请注明出处:http://blog.csdn.net/Hello_Chillax/article/details/45672601 开题:对android稍微有些了解的朋友都知道,android中有四大组件,分别是:Activity,Service,ContentProvider,BroadcastReceiver.今天来介绍其一:BroadcastReceiver. BroadcastReceiver:顾名思义,广播接收者,可以接收系统,其他应用等等发送的广播进而做出相应的反应.比如

Android 四大组件之 BroadCastReceiver

BroadCastReceiver是一种全局的监听器.用于监听系统全局的广播消息.由于他是一种全局的监听器,所以他可以轻松实现,系统中不同组件之间的通信. 1.创建BroadCastReceiver public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 当监听到广播消息时,执行这个方法. String cont

Android四大组件之BroadcastReceiver

广播接收者  现实中:电台要发布消息,通过广播把消息广播出去,使用收音机,就可以收听广播,得知这条消息 Android中:系统在运行过程中,会产生会多事件,那么某些事件产生时,比如:电量改变.收发短信.拨打电话.屏幕解锁.开机,系统会发送广播,只要应用程序接收到这条广播,就知道系统发生了相应的事件,从而执行相应的代码.使用广播接收者,就可以收听广播 创建广播接收者 1. 定义java类继承BroadcastReceiver 2. 在清单文件中定义receiver节点,定义name属性,指定广播接

android四大组件之BroadcastReceiver ip拨号功能

BroadcastReceiver是广播接收者,系统会在产生事件的时候发送一些广播,比如开机,打电话,等等…… 而BroadcastReceiver就可以接收到这些广播从而进行操作. 今天我们要做的就是在拨打号码的时候加上前面的ip号. 首先我们要注册一个BroadcastReceiver,然后我们要在清单文件里配置一些信息首先我们要明确这个BroadcastReceiver 要接收什么样的 广播. <receiver android:name="com.example.ipcall.My

android四大组件之BroadcastReceiver短信拦截功能

首先我们要配置一些清单文件 <receiver android:name="com.example.smslinser.MyReceiver" >            <intent-filter android:priority="1000">                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>   

android四大组件之BroadcastReceiver开机启动

和其他BroadcastReceiver一样需要配置接收的广播信息,然后配置权限 <receiver            android:name="com.example.kaijistart.BootReceiver" >            <intent-filter >                <action android:name="android.intent.action.BOOT_COMPLETED"/&g

android四大组件之广播接收器BroadcastReceiver

Android有一个非常重要的特性,就是广播.也可以将广播看做是通信机制.  Android四大组件: Activity, service, broadcastReceiver 和contentProvider, 只有Activity和service有完整的生命周期, 其他 broadcastReceiver 和contentProvider 都没有.  broadcastReceiver 本质上是一个监听器, 负责监听系统应用发出的广播(BroadCast). broadcastReceive

Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听

Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他所有的原理搞懂,但是最起码的,我要把他的各种使用方法了如指掌才行 BroadcastReceiver 接收系统的广播,比如电话,短信之类的 1.IP拨号器 我们在拨打电话的时候,我们系统也会事先发送一个广播,所以我们可以用广播接收者来接收到这个广播拨打电话的时候在电话号码前面加上一些优惠的长途短号,