在OSI模型中,还记得数据链路层中ARP通过广播的方式获得通信对方的MAC地址么?假如在局域网中,两台主机之间相互通信,知道对方的IP地址是不行的,必须知道对方的MAC地址,此时通过ARP发送广播。但是ARP发送的广播和Android中的广播不是一回事。Android中的广播就如监听器,用于监听系统的广播消息,它可以实现系统中不同组件之间的通信。下面就介绍广播相关的知识点吧。
广播的分类:
官方文档说明主要有两种广播类型,
普通广播:Normal broadcast通过Context.sendBroadcast()被发送,完全异步的,可以在同一时刻被所有接受者所接受,消息传输效率很高,但是意味着接受者不能将处理结果传递给下一个接受者,并且无法终止广播的传播的缺点。
有序广播:通过Context.sendOrderedBroadcast()被发送,接受者按照声明的优先级(android:priority)依次接受Broadcast,优先级越高,先接受,并且可以接受到上一级处理结果。
四大组件都需要在AndroidManifest.xml中注册,广播有两种注册方式,
静态注册:(在AndroidManifest.xml中注册)
<application
...>
...
<receiver
android:name=".MyReceiver" >
<intent-filter android:priority="50" >
<action android:name="com.example.lios" />
</intent-filter>
</receiver>
...
</application>
动态注册:(在代码中注册)
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.lios");
filter.setPriority(50);
registerReceiver(receiver, filter);
下面通过一个demo简单说明:
布局文件,只是一个简单的Button:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:gravity="center"
tools:context="com.example.broadcastreceiver.MainActivity" >
<Button
android:id="@+id/sendBroad"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="发送广播" />
</RelativeLayout>
第一个广播:public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO 自动生成的方法存根
Toast.makeText(context,"接受到的Intent的Action为:" + intent.getAction()+"广播内容是:"+intent.getStringExtra("MSG")+"MyReceiver",Toast.LENGTH_SHORT).show();
}
}
第二个广播:
public class SecondReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO 自动生成的方法存根
Toast.makeText(context,"接受到的Intent的Action为:" + intent.getAction()+"广播内容是:"+intent.getStringExtra("MSG")+"SecondReceiver",Toast.LENGTH_SHORT).show();
// abortBroadcast(); 指定发送有序广播才会中断广播传递
}
}
MainActivity类:
public class MainActivity extends Activity {
private Button sendBroad;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendBroad = (Button)findViewById(R.id.sendBroad);
sendBroad.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
ThirdReceiver receiver = new ThirdReceiver(); //静态注册ThirdReceiver
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.lios");
filter.setPriority(150);
registerReceiver(receiver, filter);
Intent intent = new Intent();
intent.setAction("com.example.lios");
intent.putExtra("MSG","我是广播");
sendBroadcast(intent); //sendOrderedBroadcast(intent,null)发送有序广播
}
});
}
public class ThirdReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO 自动生成的方法存
Toast.makeText(context,"接受到的Intent的Action为:" + intent.getAction()+"广播内容是:"+intent.getStringExtra("MSG")+"ThirdReceiver",Toast.LENGTH_SHORT).show();
}
}
}
看下效果:
大家可以发现,上面我没有发送有序广播,但是三个广播注册时都设置了优先级,所以会按照优先级的大小依次传播。如果不设置优先级的话,实际(不是逻辑上)传播顺序优先级是:动态注册 >静态注册,静态注册中的广播是按照排在前面的广播先接受,以上是实验中得出的,如果有误,麻烦指正。
上面是发送一条带有信息的Intent,action为"com.example.lios"的广播,只要注册的广播接收器且action匹配的会接受Intent中的信息。