Android四大组件之BroadcastReceiver


BroadcastReceiver:广播接收器,是一个专注于接收广播通知信息,并做出对应处理的组件

1、应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类

 2、广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息

 3、 Android中的广播事件有两种:

1)系统广播事件,比如:ACTION_BOOT_COMPLETED(系统启动完成后触发),ACTION_TIME_CHANGED(系统时间改变时触发),ACTION_BATTERY_LOW(电量低时触发)等等2)我们自定义的广播事件。

 

4、 广播时间流程:

1)注册广播事件:注册方式有两种,

一种是静态注册,就是在AndroidManifest.xml文件中定义,注册的广播接收器必须要继承BroadcastReceiver;静态注册的广播,在程序结束时,仍会监听符合的action

 另一种是动态注册,是在程序中使用Context.registerReceiver注册,注册的广播接收器相当于一个匿名类。两种方式都需要IntentFIlter。

2)发送广播事件:通过Context.sendBroadcast来发送,由Intent来传递注册时用到的Action。

 3)接收广播事件:当发送的广播被接收器监听到后,会调用它的onReceive()方法,并将包含消息的Intent对象传给它。

 注意:onReceive中代码的执行时间不要超过5s,否则Android会弹出超时dialog。


5、广播的生命周期

 一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,

  当从该函数返回后,该对象就无效的了,结束生命周期


下面通过代码来实现广播的注册与发送、接收广播

首先定义一个广播接收器,创建一个类(MyReceiver)继承BroadcastReceiver,实现其onReceive()方法

package com.BroadcastReceive.Archer;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if (action.equals("com.action.text")) {
			String msg = intent.getStringExtra("msg");
			Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
		}
	}
}

一个广播接收器可以接收来自四面八方发出的消息,所以可以在onReceive中通过intent.getAction判断接收到的action来进行不同的操作,action为系统的action或者我们自定义的action


然后需要注册广播了,有两种注册方式

静态注册

 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 静态注册广播 -->
        <receiver android:name=".MyReceiver" >
            <intent-filter>
                <action android:name="com.action.text" /> //自定义的action,为一个字符串
            </intent-filter>
        </receiver>
    </application>


动态注册:

private MyReceiver receiver = new MyReceiver(); //实例化广播接收器
    	//动态注册广播
    	IntentFilter filter = new IntentFilter();
    	filter.addAction("com.action.text");
    	registerReceiver(receiver, filter);

在Activity或Service中注册了一个BroadcastReceiver(动态注册),

当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常

我们可以在onStop()或者onDestroy()中进行解除注册

	@Override  
	protected void onDestroy() {  
	    super.onDestroy();  
	    unregisterReceiver(receiver);  
	}


发送广播

Intent intent = new Intent();
				intent.setAction("com.action.text");//为广播时间设置action
				intent.putExtra("msg", "接收广播成功");
				sendBroadcast(intent);

如果我们需要在发送广播的同时,进行数据传递,可以通过intent来传递


无序广播:

当发出广播时,所有有注册这个action的广播接收器均会接收到这个广播事件,且执行无先后顺序,相互之间不会有影响;没有注册则不会接收到


有序广播

当有多一个广播接收器注册这个action,且我们需要给他们设置接收的顺序时,这时候就要用到有序广播。

有序广播比较特殊,它每次只发送到优先级较高的接收器那里,然后由优先级高的接收器再传播到优先级低的接收器那里,优先级高的接收者有能力终止这个广播。

先定义两个广播接收器,FirstReceiver为优先级较高的接收器

public class FirstReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if (action.equals("action")) {
			String msg = intent.getStringExtra("msg");
			Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();

			Bundle bundle = new Bundle();
			bundle.putString("msg", "来自第一个广播接收器的消息");
			setResultExtras(bundle); //将一个Bundle对象设置为结果集对象,传递到下一个接收者那里
		}
	}
}
public class SecondReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if (action.equals("action")) {
			String msg = getResultExtras(true).getString("msg"); //用getResultExtras获取到经过处理的信息
			Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
		}
	}
}

注册广播时,需要给设置优先级 android:priority

        <receiver 
            android:name=".FirstReceiver">
            <intent-filter 
                android:priority="1000">  //这个属性的范围在-1000到1000,数值越大,优先级越高
                <action android:name="com.action.text"/>
            </intent-filter>
        </receiver>
        <receiver 
            android:name=".FirstReceiver">
            <intent-filter 
                android:priority="1000">  //这个属性的范围在-1000到1000,数值越大,优先级越高
                <action android:name="com.action.text"/>
            </intent-filter>
        </receiver>
        <receiver 
            android:name=".SecondReceiver">
            <intent-filter 
                android:priority="999">
                <action android:name="com.action.text"/>
            </intent-filter>
        </receiver>

发送有序广播

Intent intent = new Intent();  
intent.setAction("com.action.text");
    intent.putExtra("msg", "来自Activity的消息");  
    sendOrderedBroadcast(intent, "scott.permission.MYBROADCAST");
使用发送有序广播,第二个参数为自定义权限,为null时,表示不需要声明指定权限;不为空,表示需要声明指定权限,声明如下权限
<permission android:protectionLevel="normal"  
            android:name="scott.permission.MYBROADCAST" />
            <uses-permission android:name="scott.permission.MYBROADCAST" />

这有发出广播时,优先级最高的接收器就会先接收到广播,然后再依次传递给优先级较低的接收器

如果我们需要在某一个接收器中终止广播,可以在onReceiver()中调用如下代码

abortBroadcast();


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。