Android 中你所需要了解掌握的--四大组件之BroadcastReceiver详解

一,BroadcastReceiver是什么?

  • BroadcastReceiver用于接收程序(包括用户开发的程序和系统内建的程序)所发出的Broadcast Intent
  • 与activity、service相同的是,程序启动broadcastreceiver也只需要两步
  • 1,创建需要启动的BroadcastReceiver的Intent
  • 2,调用Context的sendBroadcast()或sendOrderedBroadcast()方法来启动指定的BroadcastReceiver。
  • 与activity、service具有完整的声明周期不同,BroadcastReceiver本质上只是一个系统级的监听器–它只负责监听各个程序所发出的Broadcast(与之不同的,比如activity中的onXxxListener只是程序级别的监听器,当程序退出时,该监听器就随之关闭了)

二、BroadcastReceiver的实现

  • 实现起来很简单,只需要重写BroadcastReceiver中的onReceiver(Context context,Intent intent)方法即可。
  • 一旦实现了BroadcastReceiver,接下来就应该指定该BroadcastReceiver能匹配的Intent,此时有两种方式。

1,使用代码进行指定,调用BroadcastReceiver的Context的RegisterReceiver(BroadcastReceiver receiver,IntentFilter filter)方法指定,例如如下代码:

IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver,filter);

2,在AndroidManifest.xml文件中进行配置,例如如下代码:

<receiver android:name=".IncomingSMSReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    <intent_filter>
</reveiver>

每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver实例,并自动触发它的onReceiver()方法,onReceiver()方法执行完成后,BroadcastReceiver实例就会被销毁。

注:
1,与activity组件不同的是,当系统通过Intent启动制定了activity组件时,如果系统没有找到合适的activity组件,则会导致程序异常终止,但是系统通过intent激发BroadcastReceiver时,如果找不到合适的BroadcastReceiver组件,应用不会有任何问题。
2,如果BroadcastReceiver的onReceive()方法不能在10s内执行完成,Android会认为该程序无响应,所以在BroadcastReceiver的onReceive()方法里不要执行一些耗时的操作

三、发送广播

在程序中发送广播十分简单,只需要调用Context的sendBroadcast(Intent intent)方法即可,这条广播将会启动intent参数所对应的BroadcastReceiver

下面示范一下如何发送Broadcast、使用BroadcastReceiver来接收广播。该程序的Activity界面中包含一个按钮,当用户点击该按钮时程序会向外发送一条广播。
MainActivity.java

package com.zt.broadcasereceivetest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    String BroadcastAction = "android.provider.Broadcast1";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button sendBroadcast;
        sendBroadcast = (Button)findViewById(R.id.sendBroadcast);
        sendBroadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建Intent对象,并用该Intent对象对外发送一条广播
                //设置Intent对象
                Intent intent = new Intent();
                //设置Intent的Action属性
                intent.setAction(BroadcastAction);
                intent.putExtra("msg","简单的消息1");
                sendBroadcast(intent);

            }
        });

    }
}

MyReceiver.java

package com.zt.broadcasereceivetest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
 * Created by 邹涛 on 2017/4/10.
 */

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"接收到的Intent的Action为: " + intent.getAction(),Toast.LENGTH_SHORT).show();
    }
}

AndroidManifest.xml 中对于MyReceiver所能接收的广播的Action的配置

<receiver android:name=".MyReceiver" >
    <intent-filter>
        <action android:name="android.provider.Broadcast1" />
    </intent-filter>
</receiver>

运行结果:

Broadcast发送接收实例,点击按钮发送广播,接收广播之后响应一个Toast

正如上面程序中看到的,当符合该MyReceiver的广播出现时,该MyReceiver的onReceive()方法将会被触发,从而在该方法中显示广播所携带的消息。

注意:上面广播程序中指定发送广播时所用的Intent的Action为 android:provider:Broadcast1,这是在AndroidManifest.xml中配置的MyReceiver所应该监听的Action。

四、有序广播

Broadcast分为两种:

  • Normal Broadcast(普通广播):完全异步,可以在同一时刻被所有接收者收到,消息传递效率高,前面代码示例则为普通广播,缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。使用Context提供的sendBroadcast()方法来发送广播。

  • Ordered Broadcast(有序广播):有序广播接收者将按照预先声明的优先级一次接受Broadcast。比如:A级别高于B,B级别高于C,那么广播先传给A,再传给B,最后传给C。有序广播接收者可以终止Broadcast Intent的传播,传播一旦终止,后面的接收者就无法接收到广播了。另外,有序广播的接收者可以将数据传递给下一个接收者使用Context提供的sendOrderedBroadcast()方法来发送有序广播。

注意:对于有序广播而言,优先接收到Broadcast的接收者可以通过setResultExtras(Bundle)方法将处理结果存入Broadcast,然后传给下一个接收者,下一个接收者通过代码:

Bundle bundle = getResultExtras(true);

来获取上一个接收者存入的数据。

下面给一段发送有序广播的示例,Activity界面中只有一个普通按钮,用于发送一条有序广播。代码如下:
MainActivity.java

package com.zt.broadcasereceivetest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    String BroadcastAction = "android.provider.Broadcast2";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button sendBroadcast;
        sendBroadcast = (Button)findViewById(R.id.sendBroadcast);
        sendBroadcast.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(BroadcastAction);
                intent.putExtra("msg","简单的消息1");
                //发送有序广播
                sendOrderedBroadcast(intent, null);

            }
        });

    }
}

MyReceiver1.java

package com.zt.broadcasereceivetest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

/**
 * Created by 邹涛 on 2017/4/10.
 */

public class MyReceiver1 extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = new Bundle();
        bundle.putString("first","第一个BroadcastReceiver存入的消息");
        setResultExtras(bundle);
        //也可以取消广播的继续传播
        //abortBroadcast();
    }
}

MyReceiver2.java

package com.zt.broadcasereceivetest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

/**
 * Created by 邹涛 on 2017/4/10.
 */

public class MyReceiver2 extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = getResultExtras(true);
        //解析前一个BroadcastReceiver所存入的key为first的消息
        String first = bundle.getString("first");
        Toast.makeText(context,"第一个BroadcastReceiver存入的消息为: "+first,Toast.LENGTH_SHORT).show();
    }
}

AndroidManifest.xml中的对于MyReceiver1、MyReceiver2所能接收到的广播的Action的配置:

<receiver android:name=".MyReceiver1" >
    <intent-filter android:priority="20">
        <action android:name="android.provider.Broadcast2"/>
    </intent-filter>
</receiver>

<receiver android:name=".MyReceiver2">
    <intent-filter android:priority="10">
        <action android:name="android.provider.Broadcast2"/>
    </intent-filter>
</receiver>

值得注意的一点是每一个BroadcastReceiver的优先级priority取值范围为-1000~1000。

根据上面配置可以看出,该程序中包含两个BroadcastReceiver,其中MyReceiver1的优先级比MyReceiver2的优先级更高,如果将MyReceiver1中的取消广播的代码注释取消,那么MyReceiver2将不会再接收到广播了。

运行结果:
有序广播运行结果

五、接收系统广播消息

除了接收用户发送的广播之外,BroadcastReceiver还有一个重要用途:接收系统广播,如果应用需要在系统特定时刻执行某些操作,就可以通过监听系统广播来实现,Android常见广播的Action常量如下:

  • ACTION_TIME_CHANGED: 系统时间被改变。
  • ACTION_DATE_CHANGED: 系统日期被改变。
  • ACTION_TIMEZONE_CHANGED: 系统时区被改变。
  • ACTION_BOOT_COMPLETED: 系统启动完成
  • ACTION_PACKAGE_CHANGED: 系统的包改变。
  • ACTION_PACKAGE_ADDED:系统添加包。
  • ACTION_PACKAGE_REMOVED:系统的包被移除。
  • ACTION_PACKAGE_RESTARTED:系统的包被重启。
  • ACTION_PACKAGE_DATA_CLEARED: 系统的包数据被清空。
  • ACTION_BATTERY_CHANGED:电池电量改变。
  • ACTION_BATTERY_LOW:电池电量低。
  • ACTION_POWER_CONNECTED:系统连接电源
  • ACTION_POWER_DISCONNECTED:系统与电源断开
  • ACTION_SHUTDOWN: 系统被关闭。

通过使用BroadcastReceiver来监听特殊的广播,即可让应用随系统执行特定的操作。

比如:开机自动运行的Service
在AndroidManifest.xml中配置LauchReceiver.java中Activity所能监听的广播的Action为 监听系统启动。

<receiver android:name=".LauchReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

在加上访问系统开机事件的权限。

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

而在LauchReceiver.java中,可以自己定义应用在Android系统开机之后所要做的动作。

六、学习总结

BroadcastReceiver使用起来较为简单,也比较容易理解,功能很强大,也很实用,可以适合于Android开发中的很多功能场景。

写博客真的是个好习惯,建议大家在学习或者了解一些新的知识点之后再博客中记录,不仅仅可以方便日后的查阅,也可以让自己对知识更加的熟悉了解。


–致我的第一篇学习记录

–邹啊涛


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值