当前位置: 代码迷 >> Android >> Android札记三十三.BroadcastReceiver使用
  详细解决方案

Android札记三十三.BroadcastReceiver使用

热度:89   发布时间:2016-04-28 00:34:20.0
Android笔记三十三.BroadcastReceiver使用
    广播是一种广泛运用在应用程序之间传输信息的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件。BroadcastReceiver本质上是一种全局监听器用于监听系统全局的广播消息并接收指定的广播,因此它可以非常方便地实现系统中不同组件之间的通信。如下为BroadcastReceiver知识点结构:
一、发送与接收广播
1.发送广播   
     广播的发送通过调用Context.sendBroadcast()、Context.sendOderedBroadcast()来实现:      
     (1)Context.sendBroadcast(Intent intent):用于发送普通广播,其中intent参数表示接收该广播的广播接收者所需要满足的条件,以及广播所传递的数据;
     (2)Context.sendOderedBroadcast(Intent intent, String receiverPermission):用于发送有序广播,intent参数同上,receiverPermission表示接收该广播的许可权限。
2.接收广播    
    广播的接收,则利用组件BroadcastReceiver是对发送出来的广播进行过滤接收并响应指定的广播。通常一个广播可以被订阅了该Intnet的多个广播接收者所接收,如同一个广播台,可以被多个多位听众收听一样。
启动BroadcastReceiver步骤:
(1)创建Intent,指定BroadcastReceiver的特征;
(2)调用Context的sendBroadcast()(发送普通广播)或sendOrderBroadcast()(发送有序广播)方法来发送广播,触发指定的BroadcasttReceiver。
    为此,当应用程序发出一个广播之后,所有匹配该Intent的BroadcastReceiver都有可能被启动。
二、广播的分类
1.普通广播
    是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高。但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。
2.有序广播
    该广播的接收者将按预先声明的优先级次序接收广播。有序广播接收者可以终止广播的传播(通过调用abortBroadcast()方法),广播的传播一旦终止,后面的接收者就无法接收到广播。另外,广播的接收者可以将数据传递给下一个接收者(通过setResultExtras(Bundle bundle)方法)。
三、BroadcastReceiver应用开发步骤
    BroadcastReceiver自身并不实现图形用户界面,但是当它收到某个消息之后,可以启动Activity作为响应,或者通过NotificationManager提醒用户,或者启动Service等等。
1.创建广播接收器。实现一个继承于BroadcastReceiver基类的子类,并实现里面的onReceiver()方法;
  1. public class MyBroadcastReceiver extends BroadcastReceiver  
  2. {  
  3.     public void onReceiver(Context context,Intent intent){  
  4.     }  
  5. }
    在onReceiver()方法中,接收了一个Intent的参数,通过它可以获取广播所携带的数据,也可以启动一个Service服务来处理耗时任务等
2.发送广播,并指定该广播的Intent属性
    广播接收者注册好了以后,并不会直接运行,必须在接收广播之后才会被调用。因此,必须首先发送广播,在Activity或Service调用Context的sendBroadcast(Intent intent)或sendOrderedBroadcast(Intent intent, String receiverPermission)发送广播。

3.注册广播接收器,指定其接收哪一个广播。
    创建完广播接收者后,并不能马上使用,还必须为它(广播接收者)注册一个指定的广播,就如同我们有了收音机后,还必须选择收听哪个频道一样。
(1)静态注册:是指在AndroidManifest.xml文件中进行注册。
  1. <receiver android:name=".MyBroadcastReceiver">  
  2.     <intent-filter>  
  3.             <action  
  4.                        android:name = "com.jiangdongguo.android.myBroadcastReceover">  
  5.             <action/>  
  6.      </intent-filter>  
  7. </receiver> 
(2)动态注册:需要在代码中动态的指定广播地址并注册,通常是在Activity或Service中调用ContextWrapper的
  1. registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法进行注册。  
  2. MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();  
  3. IntentFilter filter = new IntentFilter("com.jiangdongguo.android.myBroadcastReceover"); //指定接收哪个广播  
  4. registerReceiver(myBroadcastReceiver); 
    其中,MyBroadcastReceiver为基类BroadcastReceiver子类。注册完成后,即可接收相应的广播消息,一旦广播(Broadcast)事件发生后,系统就会创建对应的BroadcastRecevier实例,并自动触发它的onReceiver()方法,onReceiver()方法执行后,BroadcastReceiver的实例就会被销毁。
三、源码实战
实现:在Activity中启动一个广播,通过广播接收器接收该广播并作出响应。
1.MyBroadcastReceiver.java:
    继承于BroadcastReceiver子类-广播接收器,用于接收指定广播并作出相应响应。
  1. package com.example.mybroadcast;  
  2. import android.content.BroadcastReceiver;  
  3. import android.content.Context;  
  4. import android.content.Intent;  
  5. import android.widget.Toast;  
  6. /*BroadcastReceiver子类 
  7.  * 用于接收指定发送广播*/  
  8. public class MyBroadcastReceiver extends BroadcastReceiver {  
  9.  @Override  
  10.  public void onReceive(Context arg0, Intent arg1) {  
  11.   Toast.makeText(arg0, "我是BroadcastReceiver,我已经接收到发送的广播!", Toast.LENGTH_SHORT).show();  
  12.  }  
  13.  
注释:我们可以在onReceiver()方法中获取Intent携带的数据,也可以启动一个Service服务来执行耗时任务等。
2.MainActivity.java
    主Activity,用于发送一个广播,或者可以代替AdroidManifest.xml工程文件注册广播接收器
  1. package com.example.mybroadcast;  
  2. import android.app.Activity;   
  3. import android.content.Intent;  
  4. import android.content.IntentFilter;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9. public class MainActivity extends Activity {  
  10.  private Button sendBroad;  
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main);  
  15.         /*1.广播接收器注册方式二:注册一个广播接收器*/  
  16.         MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();  
  17.         IntentFilter filter = new IntentFilter("com.jiangdongguo.Android.BroadcastReceiver");  
  18.         registerReceiver(myBroadcastReceiver,filter);  
  19.          
  20.         sendBroad = (Button)findViewById(R.id.send);  
  21.         sendBroad.setOnClickListener(new OnClickListener(){  
  22.    public void onClick(View v) {  
  23.   /*2.发送一个广播,并指明其action属性*/  
  24.     //a.指明该广播的action属性  
  25.     Intent intent = new Intent("com.jiangdongguo.Android.BroadcastReceiver");  
  26.     //b.发送广播  
  27.     sendBroadcast(intent);  
  28.    }  
  29.         });  
  30.          
  31.     }  
  32. }
3.AndroidManifest.xml
    工程文件,在这里的作用是增加对BroadcastReceiver注册。
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.mybroadcast"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.     <uses-sdk  
  7.         android:minSdkVersion="8"  
  8.         android:targetSdkVersion="14" />  
  9.     <application  
  10.         android:allowBackup="true"  
  11.         android:icon="@drawable/ic_launcher"  
  12.         android:label="@string/app_name"  
  13.         android:theme="@style/AppTheme" >  
  14.         <activity  
  15.             android:name=".MainActivity"  
  16.             android:label="@string/app_name" >  
  17.             <intent-filter>  
  18.                 <action android:name="android.intent.action.MAIN" />  
  19.                 <category android:name="android.intent.category.LAUNCHER" />  
  20.             </intent-filter>  
  21.         </activity>  
  22.         <!--广播接收器注册方式一: 接收的哪一个广播-->  
  23. <!--         <receiver android:name=".MyBroadcastReceiver">  
  24.             <intent-filter >  
  25.                 <action android:name="com.jiangdongguo.Android.BroadcastReceiver"/>  
  26.             </intent-filter>  
  27.         </receiver> -->  
  28.     </application>  
  29. </manifest>  
效果演示
源码分析:
(1)如果确定需要根据广播来完成一项比较耗时的操作,则可以考虑通过Intent启动一个Service来完成操作。不应考虑使用新线程去完成耗时的操作,因为BroadcastReceiver本身的生命周期极短,可能出现的情况是子线程可能没有结束,BroadcastReceiver就已经退出了。
(2)如果广播接收者所在的进程结束了,虽然该进程内还有用户启动的新线程,但由于该进程内不包含任何活动组件,因此系统可能在内存紧张时优先结束线程。这样就可能导致BroadcastReceiver启动的子线程不能执行完成



  相关解决方案