广播简介:
(一)、广播传播机制:
广播接收器,也被称为全局事件,或系统事件。
当Android系统中任何程序有动作时,如果想通知其他程序,采用广播的方式进行传播是非常有效的。广播从理论上说,可以将一个动作传播给任意多个程序(当然,广播接收器的数量会收到系统限制)。
在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。这个广播跟我们传统意义中的电台广播有些相似之处。之所以叫做广播,就是因为它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。
广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。
Android中广播的是操作系统中产生的各种各样的事件。例如,收到一条短信就会产生一个收到短信息的事件。而Android操作系统一旦内部产生了这些事件,就会向所有的广播接收器对象来广播这些事件。
(二)、广播机制的三要素:
Android广播机制包含三个基本要素:
1、广播(Broadcast) - 用于发送广播;
2、广播接收器(BroadcastReceiver) - 用于接收广播;
3、意图内容(Intent)-用于保存广播相关信息的媒介。
Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件。
(三)、广播的生命周期:
1、广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。
2、拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死,但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。
3、如果响应一个广播信息需要很长的一段时间,一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。广播接收程序的时间限制为10秒。
广播接收器BroadcastReceiver:
BroadcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件,并且广播事件处理机制是系统级别的。比如,我们可以发出一种广播来测试是否收到短信,这时候就可以定义一个BraodcastReceiver来接受广播,当收到短信时提示用户。我们既可以用Intent来启动一个组件,也可以用sendBroadcast()方法发起一个系统级别的事件广播来传递消息。
我们也可以在自己的应用程序中开发BroadcastReceiver,然后把广播接收器这个类或者对象注册到Android操作系统上去,让操作系统知道现在有这样一个广播接收器正在等待接收Android操作系统的广播,即在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。
当有广播事件产生时,Android操作系统首先告诉注册到其上面的广播接收器产生了一个怎么样的事件,每个接收器首先判断是不是我这个接收器需要的事件,如果是它所需要的事件,再进行相应的处理。
例子,我们把骚扰电话的黑名单放到数据库中去,当接到电话时会产生一个接电话事件,事先在Android操作系统中注册一个BroadcastReceiver的对象,当产生事件的时候,会通知我们的广播接收器对象,接收器对象接收到消息之后,就会到数据库里面去取所有黑名单电话和接到的这个电话号码进行比较,如果匹配就直接挂掉。
抽象类在使用的时候需要实现其子类
public class MyReceiver extends BroadcastReceiver { /** * 接受发送过来广播的方法 * 当有人发送了广播则该方法就会执行 * * 该方法执行表示当前广播接收者的生命周期开始。 * 广播接受者的生命大概有10s左右的活跃期,10s过后处于失活状态 * 活跃期相当于一个强引用,GC不会回收,失活后,系统会根据需求进行回收。 * 所以接收到广播消息后需要尽快对其进行处理 * 如果需要做耗时操作则需要开启子线程(衍生线程)来完成 * * 广播接收者每个类实现后 都需要注册! * 静态注册:在Manifest清单文件中 * 动态注册:在Java代码中注册 * @param context 谁发送的广播这个上下文对象就是谁 * @param intent 表示传递过来的数据载体 */ @Override public void onReceive(Context context, Intent intent) { Log.d("TAG", "onReceive: 1111111真巧我也接到了这个消息"); Toast.makeText(context, intent.getStringExtra("info"), Toast.LENGTH_SHORT).show(); } }
(二)、 注册BroadcastReceiver的方法
BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:
1、静态注册:
静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
如果在清单配置文件中配置了广播接收器,那么程序在安装后会自动注册广播接收器。
静态注册方式的特点:不管该应用程序是否处于活动状态,都会进行监听。
<!--注册广播接收者 --> <receiver android:name=".MyReceiver"> <!--定义意图过滤器 过滤广播--> <intent-filter> <!--过滤标记 字符串 只要发送方的action与这个注册的action一致 就能接收到这个广播--> <action android:name="com.broadcastreceiver.MyReceiver"></action> </intent-filter> </receiver>
其中,MyReceiver为继承BroadcastReceiver的类,重写了onReceiver方法,并在onReceiver方法中对广播进行处理。<intent-filter>标签设置过滤器,接收指定action广播。
2、动态注册:
静态注册就是在AndroidManifest.xml文件中定义,注册的广播接收器必须继承BroadCastReceiver;
动态注册方式是在activity里面调用当前上下文对象的registerReceiver() 方法 来注册,和静态的内容差不多。一个形参是receiver对象,另一个是IntentFilter对象。而IntentFilter构造方法的参数是要接收的action。
动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。
动态注册广播接收器的特点,就是当用来注册的 Activity 关掉后,广播也就失效了。同时反映了静态注册的一个优势,就是无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器就是打开着的。
注册:
//动态注册广播 其实就是将清单文件中的标签代码转换成为java代码来实现 //1.创建广播接收者对象 dynamicReceiver = new DynamicReceiver(); //2.创建 意图过滤器 IntentFilter filter = new IntentFilter(); //3.添加Action filter.addAction("dynamicReceiver"); //4.注册广播 registerReceiver(dynamicReceiver, filter);
销毁:
@Override protected void onDestroy() { super.onDestroy(); //动态注册的时候需要 页面销毁的时候将这个广播接收者对象 注销掉 unregisterReceiver(dynamicReceiver); }
(三)、广播接收器的优先级:
接收的优先级可以在系统配置文件中设置(声明在intent-filter元素的android:priority属性中,数值越大优先级别越高,其取值范围为-1000到1000
<!--android:priority="200" 表示广播接收者的优先级 取值范围 -1000 到+ 1000,数值越大,优先级越高 --> <receiver android:name=".OrderBroadCastReceiver1"> <intent-filter android:priority="200"> <action android:name="orderReceiver"></action> </intent-filter> </receiver>
当然也可以在调用IntentFilter对象的setPriority()方法进行设置)
//耳机插拔广播接收者 headSetPlugReceiver = new HeadSetPlugReceiver(); IntentFilter headSetPlugFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG); headSetPlugFilter.setPriority(500); registerReceiver(headSetPlugReceiver,headSetPlugFilter);,前面的接收者可以对接收到得广播意图(Intent)进行处理,并将处理结果放置到广播意图中,然后传递给下一个接收者,当然前面的接收者有权终止广播的进一步传播。如果广播被前面的接收者终止后,后面的接收器就再也无法接收到广播了
(四)、发送广播:
//点击发送广播 //定义要传递的数据 Intent intent = new Intent(); //广播接收者在注册的时候添加的action 和这个消息内容设置的action必须保持一致 才能保证 广播接收者接收到发送的信息! //当多个广播接收者都注册了同一个action的时候,那么发送广播后 ,这些广播接收者都能够收到消息 intent.setAction("com.broadcastreceiver.MyReceiver"); intent.putExtra("info", "同学们,下星期见咯~~~!!!"); //发送方法,intent参数做为信息的数据载体 sendBroadcast(intent);
//发送有序广播 Intent intent = new Intent(); intent.setAction("orderReceiver"); intent.putExtra("info", "我是有顺序的广播"); sendOrderedBroadcast(intent, null);
(五)、注销BroadcastReceiver:
1、一般在onStart中注册BroadcastReceiver,在onStop中取消BroadcastReceiver。
2、一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)时才有效,当从该方法返回后,该对象就无效的了,结束生命周期。
//动态注册的广播要记住在activity的onDestroy回调方法中注销广播接收器
unregisterReceiver(receiver);
系统广播
常用的系统广播:
监听网络状态变化的:
public class NetStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取一个网络状态链接的管理类 ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); //获取正在活动的 网络工作信息 NetworkInfo info = manager.getActiveNetworkInfo(); if (info ==null){ //表示当前手机没有网络 Toast.makeText(context, "没有网络了", Toast.LENGTH_SHORT).show(); return; } //获取状态 int type = info.getType(); switch (type){ case ConnectivityManager.TYPE_MOBILE: //表示当前使用的是 移动数据流量 Toast.makeText(context, "使用的是手机流量啦", Toast.LENGTH_SHORT).show(); break; case ConnectivityManager.TYPE_WIFI: //表示当前使用的是 WIFI Toast.makeText(context, "使用的是WIFI了", Toast.LENGTH_SHORT).show(); break; } } }
监听手机屏幕开关的:
public class ScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_SCREEN_ON)) { Log.e("TAG", "onReceive: 手机屏幕打开了"); } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { Log.e("TAG", "onReceive: 手机屏幕关闭了"); } } }等等。