广播接收者:
BroadcastReceiver 简单地说就是接收广播意图的Java类,用于异步接收广播Intent。主要有两大类,用于接收广播的:
·有序广播 Ordered broadcasts(用 Context.sendOrderedBroadcast()发送)每次被发送到一个receiver。所谓有序,就是每个receiver执行后可以传播到下一个receiver,也可以完全中止传播--不传播给其他receiver。 而receiver运行的顺序可以通过matched intent-filter 里面的android:priority来控制,当priority优先级相同的时候,Receiver以任意的顺序运行。
要注意的是,即使是Normal broadcasts,系统在某些情况下可能会恢复到一次传播给一个receiver。 特别是receiver可能需要创建一个进程,为了避免系统超载,只能一次运行一个receiver。
Broadcast Receiver 并没有提供可视化的界面来显示广播信息。可以使用Notification和Notification Manager来实现可视化的信息的界面,显示广播信息的内容,图标及震动信息。
生命周期
一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。
因此从这个特征可以看出,在所调用的onReceive(Context, Intent)函数里,不能有过于耗时的操作,不能使用线程来执行。对于耗时的操作,请start service来完成。因为当得到其他异步操作所返回的结果时,BroadcastReceiver 可能已经无效了。
发送广播
事件的广播比较简单,构建Intent对象,可调用sendBroadcast(Intent)方法将广播发出。另外还有sendOrderedBroadcast(),sendStickyBroadcast()等方法,
接收广播
通过定义一个继承BroadcastReceiver类来实现,继承该类后覆盖其onReceiver方法,并在该方法中响应事件。
注册广播的方法:
1.静态注册:
第一步、
四大组件都需要注册,注册是用来进行反射操作的
<receiver android:name=".MyReceiver"></receiver>
第二步、
MyReceiver.java 继承BroadcastReceiver ,就像继承Activity一样
- package com.example.broadcastreceiver;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.util.Log;
- /**
- * 创建广播接收器--继承BroadcastReceiver
- */
- public class MyReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.e("TAG", "" + intent.getStringExtra("data"));
- }
- }
MainActivity
- package com.pry.broadcastreceiver;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- public class MainActivity extends Activity implements OnClickListener {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- findViewById(R.id.send_msg).setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.send_msg:
- Intent intent = new Intent(this, MyReceiver.class);
- intent.putExtra("data", "jike");
- // 发送一个消息
- sendBroadcast(intent);
- break;
- default:
- break;
- }
- }
- }
activity_main.xml
- <LinearLayout 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:orientation="vertical" >
- <Button
- android:id="@+id/send"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="发送" />
- <Button
- android:id="@+id/regist"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="注册" />
- <Button
- android:id="@+id/unregist"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="注销" />
- </LinearLayout>
MainActivity
- package com.pry.broadcastreceiver;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- public class MainActivity extends Activity implements OnClickListener {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- findViewById(R.id.send).setOnClickListener(this);
- findViewById(R.id.regist).setOnClickListener(this);
- findViewById(R.id.unregist).setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.send:
- Intent intent = new Intent(MyReceiver.ACTION);
- intent.putExtra("data", "jike");
- sendBroadcast(intent);
- break;
- case R.id.regist:
- if (receiver == null) {
- /** 如果为null,才可以进行注册接收器 */
- receiver = new MyReceiver();
- registerReceiver(receiver, new IntentFilter(MyReceiver.ACTION));
- }
- break;
- case R.id.unregist:
- /** 如果不为null,才可以注销,注销完毕,需要置为null */
- if (receiver != null) {
- // 注销
- unregisterReceiver(receiver);
- receiver = null;
- }
- break;
- default:
- break;
- }
- }
- private MyReceiver receiver = null;
- }
MyReceiver
- package com.pry.broadcastreceiver;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.util.Log;
- /**
- * 创建广播接收器--继承BroadcastReceiver
- */
- public class MyReceiver extends BroadcastReceiver {
- public static final String ACTION = "com.example.broadcastreceiver.intent.action.MyReceiver";
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.e("TAG", "" + intent.getStringExtra("data"));
一个receiver可以接收多个action的,即可以有多个intent-filter,需要在onReceive里面对intent.getAction(action name)进行判断。
个人推荐使用静态注册方式,由系统来管理receiver,而且程序里的所有receiver,可以在xml里面一目了然。而动态注册方式,隐藏在代码中,比较难发现。
而且动态注册,需要特别注意的是,在退出程序前要记得调用Context.unregisterReceiver()方法。一般在activity的onStart()里面进行注册, onStop()里面进行注销。官方提醒,如果在Activity.onResume()里面注册了,就必须在Activity.onPause()注销。
Permission权限
要接收某些action,需要在AndroidManifest.xml里面添加相应的permission。例如接收SMS:
广播类型:
1.有序广播
然而有序广播是按照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C ,调用Context.sendOrderedBroadcast(intent)发送广播;优先级别声明在 intent-filter 元素的 android:priority 属性中,数越大优先级别越高,取值范围:-1000到1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置 。
有序广播的接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。
另外,有序广播的接收者可以将数据传递给下一个接收者,如:A得到广播后,可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据。
2.普通广播
普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。
小结:
1. 对于sendBroadCast的intent对象,需要设置其action name;
2. 推荐使用显式指明receiver,在配置文件AndroidManifest.xml指明;
3. 一个receiver可以接收多个action;
4. 每次接收广播都会重新生成一个接收广播的对象,再次调用onReceive;
5. 在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理。