首先来区别两个概念:
广播与广播接收器是不同的。广播是Intent,而广播接收者是 BroadcastReceiver。contxet 发送广播(Intnet),广播接收者(BroadcastRecceiver)进行接收。
BroadcastRecevier的简介:
BroadcastReceiver是Android四大组件之一,广播是一种广泛运用的在应用程序之间传输信息的机制,而广播接收器(BroadcastReceiver) 是对发送出来的广播进行过滤接收并响应的一类组件;广播接收器( BroadcastReceiver )用于接收广播 (Intent ),广播 Intent 的发送是通过调Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 来实现的。通常一个广播 Intent 可以被订阅了此 Intent 的多个广播接收者所接收。
Android内置了很多系统级别的广播,可以在应用程序中通过监听这些广播来得到各种系统的状态信息。手机开机完成后会发出一条广播,电池的电量发生变化会发出一条广播,时间改变也会发出一条广播……如果想要接受到这些广播,就需要使用广播接收器。
BroadcastRecervier的分类:
普通广播:
发送方式:Context.sendBroadcast()
标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎会在同一时刻接收到这条广播消息,消息传递效率高,
缺点:不能处理广播传给一个接收者,不能终止广播的传播
有序广播:
发送方式:Context.sendOrderedBroadcast()
优点:可以根据广播接收器(BroadcastRecevier)在注册时的优先级依次接收传播,广播接收器可以处理广播然后再传给一下广播接收者,也可以根据需要调用abortBroadcast()终止广播传播。
缺点:效率低
astRecevier)的时候指定。广播(Intnet)分普通广播和有序广播,而广播接收器(BroadcastRecevier)是不分普通还是有序的,广播(Intnet)是普通还收有序的看context在发送时调用的方法,是context.senBroadCast(intent)普通广播,若是context.sendOrderedBroadcast(intent)是有序广播。
BroadcastRecervier的注册方式:
静态和动态两种
先看动态:
public class BoradcastActivity extends Activity {
private Button senBroadBut , senOrdBroadBut;
private BroadcastReceiver A ,B ,C , D ;
private IntentFilter intentFilter ;
private final String ACTIOM = "com.example.administrator.sharedpreferences.actiom";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.avtivty_broadcast_layout);
senBroadBut = (Button) findViewById( R.id.sendBoroad);
senOrdBroadBut = (Button) findViewById( R.id.sendOrdBoroad);
intentFilter = new IntentFilter();
intentFilter.addAction(ACTIOM);
intentFilter.setPriority(100);
registerReceiver( new BroadcastA() , intentFilter); //注册广播接收器A
intentFilter.setPriority(500);
registerReceiver( new BroadcastB() , intentFilter); //注册广播接收器B
intentFilter.setPriority(900);
registerReceiver( new BroadcastC() , intentFilter); //注册广播接收器C
//为过滤器添加处理规则(网络变化)
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//注册广播接收器
registerReceiver( new NetworkChangeReceiver(), intentFilter);
//普通广播
senBroadBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(ACTIOM);
sendBroadcast(intent);//发送普通广播
}
});
//有序广播
senOrdBroadBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(ACTIOM);
sendOrderedBroadcast( intent , null );
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver( A );
unregisterReceiver( B );
unregisterReceiver( C );
unregisterReceiver( D );
}
/**
* BoradcastRecevoier A
*/
class BroadcastA extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals( ACTIOM )){
System.out.println(" A 接收到广播 ");
}
}
}
/**
* BoradcastRecevoier B
*/
class BroadcastB extends BroadcastReceiver{
@Override
public void onReceive(Context context , Intent intent) {
if(intent.getAction().equals( ACTIOM)){
System.out.println(" B 接收到广播");
}
}
}
/**
* BoradcastRecevoier C
*/
class BroadcastC extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals( ACTIOM)){
System.out.println(" C 接收到广播");
}
}
}
//自定义内部类,继承自BroadcastReceiver
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//实现onReceive()方法的逻辑
Toast.makeText(context, "网络状态改变", Toast.LENGTH_SHORT).show();
System.out.println(" 网络状态改变");
}
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/sendBoroad"
android:text="普通广播"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/sendOrdBoroad"
android:text="有序广播"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
发送普通广播,看日志:
05-15 11:16:34.823 13741-13741/com.example.administrator.sharedpreferences I/System.out: A 接收到广播
05-15 11:16:34.823 13741-13741/com.example.administrator.sharedpreferences I/System.out: B 接收到广播
05-15 11:16:34.824 13741-13741/com.example.administrator.sharedpreferences I/System.out: C 接收到广播
发送有序广播,看日志:
05-15 11:18:01.372 16426-16426/com.example.administrator.sharedpreferences I/System.out: C 接收到广播
05-15 11:18:01.376 16426-16426/com.example.administrator.sharedpreferences I/System.out: B 接收到广播
05-15 11:18:01.378 16426-16426/com.example.administrator.sharedpreferences I/System.out: A 接收到广播
网络连接与断开时,看日志:
05-15 12:10:09.994 21490-21490/com.example.administrator.sharedpreferences I/System.out: 网络状态改变
总结:动态注册只要是使用IntnetFilter类的addActiom()声明广播接收器可以接受什么样的广播Intent,发广播时,Intent.setActiom()指明行为。
然后用context.registerRecevier(BroadcastRecevier , intnetFilter)注册;
修改 NetworkChangeReceiver 中的代码:接不用就加intnetfilter.addActiom(),效果一样 的;
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {//connectivityManger是一个系统服务类,专门用于管理网络连接
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
//调用NetworkInfo的isAvailable()方法判断是否联网
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(context,"网络已连接",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"网络不可用",Toast.LENGTH_SHORT).show();
}
}
}
注意:不要再 onReceive() 方法中添加过多的逻辑或者进行任何耗时的操作,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。广播接收器更多是扮演打开其他组件的角色,比如创建一条状态栏通知,或者启动一个服务。
静态注册:知识不注册代码写在AndroidManfifest.XML文件里面
<service
android:name="com.example.administrator.sharedpreferences.test.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</service>
动态注册于静态的注册的比较:
动态注册广播接收器可以自由地控制注册与注销,在灵活性方面有很大优势。但是它也存在一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。而静态注册可以让程序在未启动的情况下就能接收到广播。
系统广播可以被其他任何程序接收到,这样就很容易引起安全性的问题。比如我们发送的一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。为了能够简单地解决广播安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。
本地广播LocalBroadcastRecevier:
本地广播的用法并不复杂,主要就是使用了一个LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。
首先通过LocalBroadcastManager 的 getInstance() 方法得到它的一个实例,然后在注册广播接收器的时候调用的是registerReceiver()方法,在发送广播的时候调用的是 LocalBroadcastManager 的 sendBroadcast() 方法,仅此而已。看代码:
public class LocalReceiverAtivity extends Activity{
private Button but;
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_local_layout);
//获取LocalBroadcastManger实例
localBroadcastManager = localBroadcastManager.getInstance(this);
but = (Button) findViewById( R.id.but);
but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
intent.putExtra("woider","青春的逝去并不可怕,可怕的是失去了勇敢地热爱生活的心");
//发送本地广播
localBroadcastManager.sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
//本地广播接收器
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("woider");
Toast.makeText(context,data,Toast.LENGTH_SHORT).show();
}
}
}