四大组件之BroadcastReceiver详解

 

在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast

 

进行过滤接受并响应的一类组件。这种组件本质上是一种全局的监听器,用于监听系统全局的广播消息。它可以接收来自系统和应

用的的广播。


下面是Android Doc中关于BroadcastReceiver的概述:

①广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的──比如,通知时区改变、电

池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播──比如说,通知其它应用程序一些数据下载完成并

处于可用状态。

②应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。

③广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知

可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打

开它并获取消息。

下面将详细的阐述如何发送Broadcast和使用BroadcastReceiver过滤接收的过程

  首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action、Category)装入一个Intent对象,然后通过调用 sendO

 

rderBroadcast()或sendStickyBroadcast()方法,把 Intent对象以广播方式发送出去。其中sendBroadcast发送的是普通广播,

 

sendOrderedBroadcast发送的是有序广播。

  当Intent发送以后,所有已经注册的BroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用

BroadcastReceiver的onReceive()方法。所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceive()方法。onReceive

中代码的执行时间不要超过5s,否则Android会弹出超时dialog。

 

Android中的广播事件有两种,一种就是系统广播事件,比如:ACTION_BOOT_COMPLETED(系统启动完成后触发),

 

ACTION_TIME_CHANGED(系统时间改变时触发),ACTION_BATTERY_LOW(电量低时触发)等等。另外一种是我们自定义的

广播事件。

 

 

 

注册BroadcastReceiver有两种方式:

 

 

  静态注册:通过这种方式注册的广播为常驻型广播,也就是说如果应用程序关闭了,有相应事件触发,程序还是会被系统自动

调用运行。


在AndroidManifest.xml中用标签生命注册,并在标签内用标签设置过滤器。

  <receiver android:name="myRecevice">    //继承BroadcastReceiver,重写onReceiver方法

    <intent-filter>    

      <action android:name="com.dragon.net"></action> //使用过滤器,接收指定action广播

      </intent-filter>

  </receiver> 

  动态注册:这种方法是通过代码在.Java文件中进行注册。通过这种方式注册的广播为非常驻型广播,即它会跟随Activity的生命周期,所以在Activity结束前我们需要调用unregisterReceiver(receiver)方法移除它。

  IntentFilter intentFilter = new IntentFilter();

  intentFilter.addAction(String);   //为BroadcastReceiver指定action,使之用于接收同action的广播

      registerReceiver(BroadcastReceiver,intentFilter);

  一般:在onStart中注册,onStop中取消unregisterReceiver

  指定广播目标Action:Intent intent = new Intent(actionString);

 并且可通过Intent携带消息 :intent.putExtra("msg", "我通过广播发送消息了");

  发送广播消息:Context.sendBroadcast(intent )

注意:如果我们在Activity中注册了BroadcastReceiver,当这个Activity销毁的时候要主动撤销注册否则会出现异常。

Broadcast的类型有两种:普通广播和有序广播。

 

 

Normal broadcasts(普通广播):Normal broadcasts是完全异步的可以同一时间被所有的接收者接收到。消息的传递效率比较高。

 

 

但缺点是接收者不能讲接收的消息的处理信息传递给下一个接收者也不能停止消息的传播。

 

Ordered broadcasts(有序广播):Ordered broadcasts的接收者按照一定的优先级进行消息的接收。如:A,B,C的优先级依次降

 

低,那么消息先传递给A,在传递给B,最后传递给C。优先级别声明在中,取值为[-1000,1000]数值越大优先级别越高。优先级也可

通过filter.setPriority(10)方式设置。 另外Ordered broadcasts的接收者可以通过abortBroadcast()的方式取消广播的传播,也可以通过

setResultData和setResultExtras方法将处理的结果存入到Broadcast中,传递给下一个接收者。然后,下一个接收者通过

getResultData()和getResultExtras(true)接收高优先级的接收者存入的数据。

 

BroadcastReceiver的生命周期,从对象调用它开始,到onReceiver方法执行完成之后结束。另外,每次广播被接收后会重新创建

 

BroadcastReceiver对象,并在onReceiver方法中执行完就销毁,如果BroadcastReceiver的onReceiver方法中不能在10秒内执行完

成,Android会出现ANR异常。所以不要在BroadcastReceiver的onReceiver方法中执行耗时的操作。


如果需要在BroadcastReceiver中执行耗时的操作,可以通过Intent启动Service来完成。但不能绑定Service。

 

 

特别是,您可能无法从一个BroadcastReceiver中显示一个对话框,或绑定到服务。对于前者,则应该使用NotificationManager的

 

 

API。对于后者,你可以使用Context.startService()来启动一个Service。


举个栗子:

Step1:在MainActivity的onStart方法中注册广播事件。静态注册方式是在AndroidManifest.xml文件中。

Step2: 点击相应按钮后会触发相应的方式来发送广播消息。


/** 
 * MainActivity
 */  
public class MainActivity extends Activity {  
    private Button sendStaticBtn;  
    private Button sendDynamicBtn;  
    private Button sendSystemBtn;  
    private static final String STATICACTION = "com.byread.static";  
    private static final String DYNAMICACTION = "com.byread.dynamic";  
    // USB设备连接  
    private static final String SYSTEMACTION = Intent.ACTION_POWER_CONNECTED;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        sendStaticBtn = (Button) findViewById(R.id.send_static);  
        sendDynamicBtn = (Button) findViewById(R.id.send_dynamic);  
        sendSystemBtn = (Button) findViewById(R.id.send_system);  
        sendStaticBtn.setOnClickListener(new MyOnClickListener());  
        sendDynamicBtn.setOnClickListener(new MyOnClickListener());  
        sendSystemBtn.setOnClickListener(new MyOnClickListener());  
    }  
    class MyOnClickListener implements OnClickListener{  
        @Override  
        public void onClick(View v) {  
            // 发送自定义静态注册广播消息  
            if(v.getId() == R.id.send_static){  
                Log.e("MainActivity", "发送自定义静态注册广播消息");  
                Intent intent = new Intent();  
                intent.setAction(STATICACTION);  
                intent.putExtra("msg", "接收静态注册广播成功!");  
                sendBroadcast(intent);  
            }  
            // 发送自定义动态注册广播消息  
            else if(v.getId() == R.id.send_dynamic){  
                Log.e("MainActivity", "发送自定义动态注册广播消息");  
                Intent intent = new Intent();  
                intent.setAction(DYNAMICACTION);  
                intent.putExtra("msg", "接收动态注册广播成功!");  
                sendBroadcast(intent);  
            }  
          
        }  
    }  
    @Override  
    protected void onStart() {  
        super.onStart();  
        Log.e("MainActivity", "注册广播事件");  
        // 注册自定义动态广播消息  
        IntentFilter filter_dynamic = new IntentFilter();  
        filter_dynamic.addAction(DYNAMICACTION);  
        registerReceiver(dynamicReceiver, filter_dynamic);  
    }  
    private BroadcastReceiver dynamicReceiver = new BroadcastReceiver() {  
          
        @Override  
        public void onReceive(Context context, Intent intent) {  
            Log.e("MainActivity", "接收自定义动态注册广播消息");  
            if(intent.getAction().equals(DYNAMICACTION)){  
                String msg = intent.getStringExtra("msg");  
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();  
            }  
        }  
    };  
  
}  

 

 

 

Step3:接收广播消息。以下为两个静态注册的广播接收器


/** 
 * 自定义静态注册广播消息接收器 
 * @author zuolongsnail 
 * 
 */  
public class StaticReceiver extends BroadcastReceiver {  
  
    @Override  
    public void onReceive(Context context, Intent intent) {  
        String msg = intent.getStringExtra("msg");  
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();  
    }  
}  



/** 
 * 系统静态注册广播消息接收器 
 *  
 */  
public class SystemReceiver extends BroadcastReceiver {  
  
    @Override  
    public void onReceive(Context context, Intent intent) {  
        if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {  
            Log.e("SystemReceiver", "电量低提示");  
            Toast.makeText(context, "您的手机电量偏低,请及时充电", Toast.LENGTH_SHORT).show();  
        }  
    }  
}  
下面是AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    package="com.byread" android:versionCode="1" android:versionName="1.0">  
    <application android:icon="@drawable/icon" android:label="@string/app_name">  
        <activity android:name=".MainActivity" android:label="@string/app_name">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
        <!-- 注册自定义静态广播接收器 -->  
        <receiver android:name=".StaticReceiver">  
            <intent-filter>  
                <action android:name="com.byread.static" />  
            </intent-filter>  
        </receiver>  
        <!-- 注册系统静态广播接收器 -->  
        <receiver android:name=".SystemReceiver">  
            <intent-filter>  
                <action android:name="android.intent.action.BATTERY_LOW" />  
            </intent-filter>  
        </receiver>  
    </application>  
</manifest>  

 

大概就样啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值