您的位置:首页 > 移动开发 > Android开发

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

2017-04-10 13:53 435 查看

一,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>


运行结果:



正如上面程序中看到的,当符合该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:系统的包被重启。
a258

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开发中的很多功能场景。

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

–致我的第一篇学习记录

–邹啊涛
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: