关闭

四大组件之BroadcastReceiver

162人阅读 评论(0) 收藏 举报
分类:


广播接收者:


BroadcastReceiver 简单地说就是接收广播意图的Java类,用于异步接收广播Intent。主要有两大类,用于接收广播的:


· 正常广播 Normal broadcasts(用 Context.sendBroadcast()发送)是完全异步的。它们都运行在一个未定义的顺序,通常是在同一时间。这样会更有效,但意味着receiver不能包含所要使用的结果或中止的API。

  ·有序广播 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一样

[java] view plaincopy
  1. package com.example.broadcastreceiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. /** 
  9.  * 创建广播接收器--继承BroadcastReceiver 
  10.  */  
  11. public class MyReceiver extends BroadcastReceiver {  
  12.   
  13.     @Override  
  14.     public void onReceive(Context context, Intent intent) {  
  15.         Log.e("TAG""" + intent.getStringExtra("data"));  
  16.     }  
  17. }  
第三步、在主界面进行发送Intent,然后在接收器中接受即可(布局只有一个button)

MainActivity

[java] view plaincopy
  1. package com.pry.broadcastreceiver;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.Menu;  
  7. import android.view.MenuItem;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10.   
  11. public class MainActivity extends Activity implements OnClickListener {  
  12.   
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.activity_main);  
  17.   
  18.         findViewById(R.id.send_msg).setOnClickListener(this);  
  19.     }  
  20.   
  21.     @Override  
  22.     public void onClick(View v) {  
  23.         switch (v.getId()) {  
  24.         case R.id.send_msg:  
  25.             Intent intent = new Intent(this, MyReceiver.class);  
  26.             intent.putExtra("data""jike");  
  27.             // 发送一个消息  
  28.             sendBroadcast(intent);  
  29.   
  30.             break;  
  31.   
  32.         default:  
  33.             break;  
  34.         }  
  35.     }  
  36.   
  37. }  
2.动态注册:

activity_main.xml

[html] view plaincopy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.      <Button  
  8.         android:id="@+id/send"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="发送" />  
  12.     <Button  
  13.         android:id="@+id/regist"  
  14.         android:layout_width="wrap_content"  
  15.         android:layout_height="wrap_content"  
  16.         android:text="注册" />  
  17.       
  18.         <Button  
  19.         android:id="@+id/unregist"  
  20.         android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:text="注销" />  
  23.   
  24. </LinearLayout>  

MainActivity

[java] view plaincopy
  1. package com.pry.broadcastreceiver;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.content.IntentFilter;  
  6. import android.os.Bundle;  
  7. import android.view.Menu;  
  8. import android.view.MenuItem;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11.   
  12. public class MainActivity extends Activity implements OnClickListener {  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.         findViewById(R.id.send).setOnClickListener(this);  
  19.         findViewById(R.id.regist).setOnClickListener(this);  
  20.         findViewById(R.id.unregist).setOnClickListener(this);  
  21.     }  
  22.   
  23.     @Override  
  24.     public void onClick(View v) {  
  25.         switch (v.getId()) {  
  26.         case R.id.send:  
  27.             Intent intent = new Intent(MyReceiver.ACTION);  
  28.             intent.putExtra("data""jike");  
  29.             sendBroadcast(intent);  
  30.             break;  
  31.         case R.id.regist:  
  32.   
  33.             if (receiver == null) {  
  34.                 /** 如果为null,才可以进行注册接收器 */  
  35.                 receiver = new MyReceiver();  
  36.                 registerReceiver(receiver, new IntentFilter(MyReceiver.ACTION));  
  37.             }  
  38.             break;  
  39.         case R.id.unregist:  
  40.             /** 如果不为null,才可以注销,注销完毕,需要置为null */  
  41.             if (receiver != null) {  
  42.                 // 注销  
  43.                 unregisterReceiver(receiver);  
  44.                 receiver = null;  
  45.             }  
  46.             break;  
  47.   
  48.         default:  
  49.             break;  
  50.         }  
  51.     }  
  52.   
  53.     private MyReceiver receiver = null;  
  54. }  

MyReceiver

[java] view plaincopy
  1. package com.pry.broadcastreceiver;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. /** 
  9.  * 创建广播接收器--继承BroadcastReceiver 
  10.  */  
  11. public class MyReceiver extends BroadcastReceiver {  
  12.   
  13.     public static final String ACTION = "com.example.broadcastreceiver.intent.action.MyReceiver";  
  14.   
  15.     @Override  
  16.     public void onReceive(Context context, Intent intent) {  
  17.         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 去处理。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:13523次
    • 积分:489
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:6篇
    • 译文:0篇
    • 评论:0条