首页 > 代码库 > 第五十九讲:四大组件之BroadcastReceiver(二)

第五十九讲:四大组件之BroadcastReceiver(二)

没有任何动物比蚂蚁更勤奋,然而它却最沉默寡言。


本讲内容: Broadcast Receiver 广播接收者的使用 


上一讲我们讲解了一个接收者来接收广播,如果有多个接收者都注册了相同的广播地址,又会是什么情况呢,这就涉及到普通广播和有序广播的概念了。


一、普通广播(Normal Broadcast)

普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的接收动作。

我们新建二个BroadcastReceiver,演示一下这个过程,FirstReceiver、SecondReceiver的代码如下:

public class FirstReceiver extends BroadcastReceiver {
	private static final String TAG = "MyReceiver";
	@Override
	public void onReceive(Context context, Intent intent) {
			Log.i(TAG, "----FirstReceiver----");
	}
}

public class SecondReceiver extends BroadcastReceiver {
	private static final String TAG = "MyReceiver";
	@Override
	public void onReceive(Context context, Intent intent) {
			Log.i(TAG, "----SecondReceiver----");
	}
}

下面是MainActivity.java主界面文件:

public class MainActivity extends Activity implements OnClickListener{
	private Button b;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		b=(Button) findViewById(R.id.b);
		b.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		// 定义一个intent
		Intent intent=new Intent().setAction("android.intent.action.MY_BROADCAST");
		// 广播出去
		sendBroadcast(intent);
	}
}

静态注册

 <receiver android:name=".FirstReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver android:name=".SecondReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.MY_BROADCAST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

点击按钮


可看到这二个接收者都接收到这条广播了,如果我们在onReceive方法的最后一行添加以下代码,试图终止广播:

abortBroadcast(); 
再次点击按钮,我们会发现,控制台中二个接收者仍然都打印了自己的日志,表明接收者并不能终止广播。


二、有序广播(Ordered Broadcast)

它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。FirstReceiver、SecondReceiver的代码如下:

public class FirstReceiver extends BroadcastReceiver {
	private static final String TAG = "MyReceiver";
	@Override
	public void onReceive(Context context, Intent intent) {
		String msg=intent.getStringExtra("msg");
		Log.i(TAG, "FirstReceiver: "+msg);
		
		Bundle bundle=new Bundle();
		bundle.putString("msg", msg+"@FristReceiver");
		setResultExtras(bundle);
	}
}
注意:在FirstReceiver中最后都使用了setResultExtras方法将一个Bundle对象设置为结果集对象,传递到下一个接收者那里,这样以来,优先级低的接收者可以用getResultExtras获取到最新的经过处理的信息集合。
public class SecondReceiver extends BroadcastReceiver {
	private static final String TAG = "MyReceiver";
	@Override
	public void onReceive(Context context, Intent intent) {
		String msg=getResultExtras(true).getString("msg");
		Log.i(TAG, "SecondReceiver: "+msg);
	}
}


下面是MainActivity.java主界面文件:

public class MainActivity extends Activity implements OnClickListener{
	private Button b;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		b=(Button) findViewById(R.id.b);
		b.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		Intent intent=new Intent().setAction("android.intent.action.MY_BROADCAST");
		intent.putExtra("msg", "hello receiver");
		sendOrderedBroadcast(intent, "permission.MY_BROADCAST_PERMISSION"); 
	}
}

注意:使用sendOrderedBroadcast方法发送有序广播时,需要一个权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。这样做是从安全角度考虑的,例如系统的短信就是有序广播的形式,一个应用可能是具有拦截垃圾短信的功能,当短信到来时它可以先接受到短信广播,必要时终止广播传递,这样的软件就必须声明接收短信的权限。

所以我们在AndroidMainfest.xml中定义一个权限:

 <permission android:protectionLevel="normal"  
            android:name="permission.MY_BROADCAST_PERMISSION" /> 

然后声明使用了此权限:

<uses-permission android:name="permission.MY_BROADCAST_PERMISSION" />  


静态注册

现在这二个接收者的<intent-filter>多了一个android:priority属性,并且依次减小。这个属性的范围在-1000到1000,数值越大,优先级越高。

      <receiver android:name=".FirstReceiver" >
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.MY_BROADCAST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <receiver android:name=".SecondReceiver" >
            <intent-filter android:priority="999">
                <action android:name="android.intent.action.MY_BROADCAST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

点击按钮


我们看到接收是按照顺序的,第一个在结果集中加入了自己的标记,并且向优先级低的接收者传递下去。

如果我们修改FirstReceiver的代码,在onReceive方法的最后一行添加以下代码,试图终止广播:

abortBroadcast(); 

然后再次运行程序,控制台打印如下:



只有第一个接收者执行了,可以看出广播可以被第一个接收者终止。


本讲就到这里,Take your time and enjoy it




第五十九讲:四大组件之BroadcastReceiver(二)