广播接收器简介
在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。
四大组件之中的广播接收器(BroadcastReceiver)也是我比较常用但是却用得较为迷糊的一个组件。一直以为广播是四大组件之一,其实,它的接收器((BroadcastReceive)才是。现在就为自己总结一下
既然是安卓组件,那就少不了要在AndroidManifest.xml中进行注册使用。其中manifest单词的意思是货单、清单。但是,相比于Activity和Service组件而言,
广播接收器的注册方式不仅限于静态的在AndroidMainfest中注册,还可以调用ContextWrapper的registerReceiver()方法进行动态注册,但是动态注册的话,需要在退出程序的时候解除注册,否则会报错提醒没有进行解除注册,所以谨记解除注册。
关于动态注册。
在谷歌官方API中有这么一句话:
Note: If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause().
这只是一句提醒而已,但是网上有人建议在onResume()中进行动态注册,然后在onPause()中解除注册,说这样能够减轻系统的负载和内存消耗,不用一直接受广播。
但是不排除有些时候在熄屏的时候需要用到广播。
所以我觉得是网上的同学们一句善意的提醒。怎么用还是按国情需要见仁见智具体分析啦。
应用广播实例
本案例为:
发送广播---->接收器响应---->另外APP中的接收器响应(该APP启动和没有启动都没有关系)
实现广播接收器的接口
package zy.zh.broadcastdemo;
public class DemoReceiver extends BroadcastReceiver {
private int count = 0;
/**
* 因为特殊的10秒生命周期,每次接收广播都会实例化一次
*/
public DemoReceiver() {
super();
count++;
Log.i(getClass().getSimpleName(),
"DemoReceiverServe Construct count = " + count);
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,
"同进程接收广播onReceiver, Msg=" + intent.getExtras().getString("Msg"),
Toast.LENGTH_LONG).show();
Log.i(getClass().getSimpleName(), "同进程接收广播called onReceive");
}
}
注册接收器组件(动态和静态都可以):
AndroidManifest.xml中静态注册:
<receiver
android:name="zy.zh.broadcastdemo.SecondReceiver"
android:exported="true" >
<intent-filter>
<action android:name="zh_demo_filter" />
</intent-filter>
</receiver>
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("zh_demo_filter");
registerReceiver(new DemoReceiver(), filter);
registerReceiver(new SecondReceiver(), filter);
}
}
发送广播:
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("zh_demo_filter");
intent.putExtra("Msg", "hello BroadCast");
sendBroadcast(intent);
}
});
以上是在同一个应用中进行的。下面要跨进程的在另外一个应用中监听该广播:
实现接收器接口:
public class ClientReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String reuslt = "跨进程客户端 onReceiver, Msg=" + intent.getExtras().getString("Msg");
Toast.makeText(context,
reuslt,
Toast.LENGTH_LONG).show();
Log.i(getClass().getSimpleName(),getClass().getSimpleName()+reuslt);
}
}
静态注册:因为静态注册方式的特点:不管该应用程序是否处于活动状态,都会进行监听。
<receiver
android:name="zy.zh.broadcastclient.ClientReceiver"
android:exported="true" >
<intent-filter>
<action android:name="zh_demo_filter" />
</intent-filter>
</receiver>
运行程序:
可怜的生命周期
BroadcastReceiver本质上是一个系统级的监听器,它专门负责监听各个程序所发出来的Broadcast,
每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver的实例,并且自动触发它的onReceive()方法,onReceive()方法执行完后,BroadcastReceiver的实例就会被销毁。
我亲手试验了,可以接收不同程序的广播,就算是BroadcastReceiver所在的App没有启动(刚开机),可完全可以接收都其他APP发出来的广播。
所以,4大组件之间的关系,都是在不同进程中进行的,特别是BroadcastReceiver,尤为特别,不过我喜欢,因为他居然可以监听到系统开机的广播,干的漂亮。
这已经是明显的IPC了这个组件。
与Activity组件更加给力的地方是,当系统通过Intent启动指定的Activity组件时,如果系统找不到合适的Activity组件,会导致程序异常终止,。但是系统通过Intent激发BroadcastReceiver时,找不到合适的BroadcastReceiver组件,应用没有任何问题一切照旧。
每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver的实例,并自动触发它的onReive()方法,onRceive()方法执行完后,BroadcastReceiver的实例就会被销毁。所谓的对应的BroadcastReceiver的实例,就是所以APP的AndroidManifestt配置文件中注册到的接收器都会被实例化,然后销毁,下次还有广播,再重新实例化一个新的,然后触发它的onReive()。
如果BroadcastReceive的onReceive()方法不能在10秒内执行完成,Android会认为该程序无响应。所以不要在onReceive()方法里执行一些耗时的操作,否则就会弹出ANR(Application No Response)的对话框。
如果这样,有耗时操作的话,请联系Service。
关于广播方式
普通广播:sendBroadcast(intent);
有序广播:sendOrderedBroadcast(intent,null);
粘性广播:sendStickyBroadcast(intent);
后续了解,to be continue........
手写总结,转载请注明出处http://blog.csdn.net/dreamintheworld/article/details/38532119