什么是广播
广播(boradcast)本质上是组件之间的通讯方式,组件之间的通讯方式有很多,像intent等等。而广播的好处就在于广播的收发机制基本独立。发出广播的只管发出广播,广播接收器只管接受相应的广播内容而不必要去关心这两个组件的其他东西,甚至说一个广播可以有多个广播接收器,这便是广播的优势所在。
发送第一条广播
android有很多系统广播,比如手机开机,时间的变化,网络状态的改变等等情况,系统都会发出一条广播,而我们的第一条广播就是监听网络变化的广播。
用此方法
public clas MainActivity extends Activity(){
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//添加名为android.net.conn.CONNECTIVITY_CHANG的action,生成广播
networkChangeReceiver = new NetworkChangeReceiver();//生成广播接收器实例
registerReceiver(networkChangeReceiver,intentFilter);//广播和接收器连接起来
}
@Override
protected void onDestroy(){
super.onDestroy();
unregistrReceiver(networkChangeReceiver);//广播取消注册
}
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context,"network changes",Toast.LANGTH_SHORT).show();
//接收到广播后显示Toast
}
}
}
动态广播与静态广播
动态广播
在“发送第一条广播”中给大家呈现的广播其实就是动态广播,动态广播是在代码中进行注册的,可以自由地控制和注册,使用起来非常灵活,但是也有一个非常致命的缺点。因为动态广播是随着代码onCreate()的运行来进行生成,结束的,所以必须要在程序启动之后才能接收到广播,如果我们想在程序启动之前就可以接收相应的广播,最好的例子就是APP的自启动了。
静态广播
public class BootConleteRecevier extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();
}
}
这里我们不再用内部类的方式来定义广播接收器,而是新建了一个继承自BroradcastReceiver的外部类,所以需要去AndroidManifest对这个广播接收器进行注册:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".BootConleteRecevier">//注册的广播接收器的名字
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">//接受的广播
</intent-filter>
</receiver>
这里我们使用了receiver标签,所有的静态注册的广播接收器都是在这里进行注册的。另外监听系统的开机广播是需要声明权限的,我们则需要用uses-permission来声明权限。
广播机制
android中的广播可以分为两类,标准广播和有序广播。
标准广播
标准广播是一种完全异步执行的广播,通俗来讲的话来讲,标准广播就像操场上的大喇叭,校长一喊话全校师生都能听得见,没有先后之分。这种广播效率高,但是也无法被截断。
首先,新建一个MyBroadcastReceiver继承自BroadcastReceiver:
public class MyBroadcastReceiver extends BroadcastReceiver { //广播接收器
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceive",
Toast.LENGTH_SHORT).show();
}
}
在AndroidManifest中对广播接收器进行注册:
<receiver android:name=".BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
通过按钮触发广播:
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(
"com.example.broadcasttest.LOCAL_BROADCAST");
sendBroadcast(intent);
}
});
有序广播
如果说标准广播像校长在大喇叭上的讲话,那有序广播就像小明找小红,但是小明不知道小红是那个班的,所以就一个班一个班的找。像这样广播就有了一个先后顺序,而且如果小明找到了小红,小明就不会再去下一个班级去继续寻找,在广播里,这就叫做广播截断,以阻止广播的继续传播。
在这里为了演示需要,我们在新的项目下再创建一个新的广播接收器AnotherBroadcastReceiver,广播是一种可以跨进程的通讯方式,所以我们应用程序内发出的广播,其他的应用程序也可以收到。
public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in AnotherBroadcastReceiver",
Toast.LENGTH_SHORT).show();
}
}
同样在相应项目的AndroidManifest中对广播接收器进行注册。
<receiver
android:name=".AnotherBroadcastReceiver" >
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
在这里我们仍然使用的是MY_BROADCAST广播。运行程序之后,当我们继续发出MY_BROADCAST广播后就会出现两次Toast提示。
然后我们修改发出广播的项目里的MainActivity中的代码
public void onClick(View v) {
Intent intent = new Intent(
"com.example.broadcasttest.LOCAL_BROADCAST");
sendOrderedBroadcast(intent,null); //修改的代码
}
这里我们只修改了一行代码,将sendBroadcast()改成sendOrderBroadcast()方法,第二个参数是一个与权限相关的字符串,现在还不做解释。这样我们的广播就变成了一个有序广播了。然后我们为广播接收器设置优先级,优先级比较高的接收器可以优先接受广播。
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100">//设置优先级
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
这里我们将MyBroadcastReceiver的优先级设置为100以保证其首先收到广播,然后我们设置当MyBroadcastReceiver收到广播后,将广播截断。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceive",
Toast.LENGTH_SHORT).show();
abortBroadcast(); //广播截断
}
}
使用本地广播
前面我们使用的广播都是系统全局广播,即发出的广播可以被其他应用接收,下面我们讲一下本地广播机制。
本地广播机制并不复杂,主要是使用了一个LocalBroadcastManager来对广播进行管理,并且提供了专门的发送广播,注册广播接收器的方法。
public class MainActivity extends Activity {
private IntentFilter intentFilter; //本地广播接收器
private LocalReceiver localReceiver; //本地广播
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this);//获得广播实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(
"com.example.broadcasttest.LOCAL_BROADCAST");//生成广播Intent
localBroadcastManager.sendBroadcast(intent);//载入intent并且发送广播
}
});
intentFilter = new IntentFilter(); //动态注册的方法
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver(); //生成本地广播接收器
localBroadcastManager.registerReceiver(localReceiver, intentFilter);//广播接收器与广播进行绑定
}
注:本地广播我发通过静态注册的方式来接收。