BroadcastReceiver是Android四大组件之一,扮演着广播发布者和广播接收者的重要角色。它主要用于接收或监听应用程序发送的广播,并根据需要作出相应的响应。BroadcastReceiver在不同的组件间通信中发挥着重要作用,包括应用内组件之间的交互以及不同应用程序之间的通信。
BroadcastReceiver的主要作用包括监听系统资源的变化,例如网络状态变化、SD卡状态等;实现多进程通信;在应用程序之间进行广播通信。它的实现原理基于消息发布者/消息订阅者模型,通过Binder机制实现消息中心AMS(ActivityManagerService)和广播接受者之间的通信。
具体来说,消息发布者(如sendBroadcast和sendOrderedBroadcast)通过Binder机制向消息中心AMS发送广播。AMS会根据广播发布者的要求,在已注册的列表中寻找是否有匹配的订阅者。如果找到了匹配的订阅者,消息中心AMS将向订阅者发送对应的广播。消息中心AMS寻找订阅者的依据是意图过滤器(IntentFilter)和权限(permission)。
当广播接收者(BroadcastReceiver)收到广播后,它会回调onReceiver方法来处理接收到的广播。要实现广播接收功能,需要继承BroadcastReceiver类,并重写onReceiver方法。当有广播发送时,如果与已注册的意图过滤器相匹配,该方法将被自动调用。
在应用程序中注册广播接收器有两种方式:静态注册和动态注册。静态注册是在AndroidManifest文件中声明,属性包括receiverName(接收者的名称)、permission(权限)、enabled(是否启用)等。而动态注册则需要在代码中使用Context.registerReceiver()方法进行注册。
总之,BroadcastReceiver作为Android四大组件之一,在实现不同组件间的通信、监听系统资源变化以及实现多进程通信等方面发挥了重要作用。通过继承BroadcastReceiver类并重写onReceiver方法,可以方便地实现广播接收功能。同时,静态注册和动态注册的方式也使得广播接收器的注册和管理更加灵活。
//默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false android:exported=["true" | "false"] android:icon="drawable resource" android:label="string resource" //继承BroadcastReceiver子类的类名 android:name=".mBroadcastReceiver" //具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收; android:permission="string" //BroadcastReceiver运行所处的进程 //默认为app的进程,可以指定独立的进程 //注:Android四大基本组件都可以通过此属性指定自己的独立进程 android:process="string">
静态注册,在App首次启动并会实例化BroadcastReceiver类,同时广播接受器也会注册到AMS中。也就是说App一启动会回调onReceiver方法。
提升广播的优先级可在intent-filter中设置属性priority,值越大优先级就越高。
在Android开发中,我们可以通过动态注册的方式来接收广播。首先,我们需要创建一个BroadcastReceiver类,例如MyBroadcastReceiver。然后,在AndroidManifest.xml文件中声明这个类,并设置intent-filter来指定接收的广播类型和优先级。具体代码如下:
```xml
```
接下来,我们可以使用Content的registerReceiver方法来动态注册这个BroadcastReceiver。具体代码如下:
```java
public abstract Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler, @RegisterReceiverFlags int flags);
```
其中,receiver参数是用于处理接收到的广播的BroadcastReceiver对象,filter参数是意图过滤器,用于设置广播的优先级及接受广播类型。broadcastPermission参数是设置广播的权限,即发送的广播意图(Intent)必须含有相同的字符串。scheduler参数是设置广播接受器接受处理消息的所在线程(onReceiver),可选,默认是在主线程。flags参数是一些附加标志选项,可选。
下面是一个使用registerReceiver方法注册广播的例子:
```java
// 注册广播
MyBroadcastReceiver mReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
// 必须action的匹配规则,否则无法接收到消息,在发送广播的意图中必须匹配action的字符串
filter.addAction("test");
registerReceiver(mReceiver, filter);
// 发送广播
Intent intent = new Intent();
intent.setAction("test");
sendBroadcast(intent);
```
在Android开发中,广播(Broadcast)是一种实现组件间通信的方式。为了避免内存泄漏,我们需要在适当的时候注销广播接收器(BroadcastReceiver)。一般来说,我们可以在onDestroy()或者onPause()方法中注销广播接收器。如果不注销,可能会导致内存泄漏。
在动态注册广播接收器时,需要注意不能重复创建新的MyBroadcastReceiver对象进行注册,否则会多次回调onReceiver方法,带来一些额外的问题。
广播可以分为以下几种类型:
1. 普通广播(Normal Broadcast):在应用的首页注册广播接收器(BroadcastReceiver),并设置匹配字段action。当通过Intent意图发送广播时,意图必须添加与注册时相同的action字符串,否则无法收到广播。当接收到广播后,会主动回调BroadcastReceiver中的onReceive方法。
2. 系统广播(System Broadcast):这些广播是由系统自动发送的,如开机、关机等。开发者无需手动注册和注销。
3. 有序广播(Ordered Broadcast):这些广播具有优先级,当多个相同类型的广播同时发送时,只有优先级最高的广播会被接收。开发者可以通过设置IntentFilter的priority属性来控制广播的优先级。
4. 粘性广播(Sticky Broadcast):这些广播会在设备重启后仍然存在,直到应用程序卸载。开发者需要在Manifest文件中声明这些广播,并在onReceive方法中处理接收到的广播。
5. App应用内广播(Local Broadcast):这些广播只在当前应用程序内有效。开发者可以使用LocalBroadcastManager类来发送和接收这些广播。
下面是一个简单的示例代码:
```java
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
private MyBroadcastReceiver mReceiver = new MyBroadcastReceiver();
private IntentFilter filter = new IntentFilter();
filter.addAction("test");
registerReceiver(mReceiver, filter);
```
重构后的内容如下:
```java
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "BroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: " + intent.getAction());
}
}
```
系统广播(System Broadcast)在Android系统中有多种,当系统状态信息发生变化时,会发出相应的广播。例如,开机、电量变化、网络变化等。在注册和发送广播时,虽然需要相同的action,但对于系统广播,其action也是有所不同的。在Android系统中,系统广播的action有以下几种:
1. `android.intent.action.BOOT_COMPLETED`:系统启动完成后发出的广播。
2. `android.intent.action.NEW_DOCKPING_STATE`:设备进入新的停靠状态时发出的广播。
3. `android.intent.action.PACKAGE_REPLACED`:一个新版本的已安装应用替换已安装的应用时发出的广播。
4. `android.intent.action.QUICK_BOOT_COMPLETED`:快速启动完成后发出的广播。
5. `android.intent.action.SCREEN_OFF`:屏幕关闭时发出的广播。
6. `android.intent.action.SCREEN_ON`:屏幕开启时发出的广播。
7. `android.intent.action.USER_PRESENT`:用户返回到设备时发出的广播。
当使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播。也可以以动态注册方式:
- 静态注册:在AndroidManifest.xml中创建一个BroadcastReceiver并指定其要监听的action。
- 动态注册:在代码中创建一个BroadcastReceiver并为其指定要监听的action。
有序广播(Ordered Broadcast)是Android中的另一种广播发送方式。在同一时刻同一条广播被一个广播接收器接收到这条消息后,必须先执行完当前广播接收器的业务逻辑后,才会继续传递广播。有序广播是有先后顺序接收的,接收规则如下:在默认情况下,相同的注册方式下,会按照注册顺序先后接收;按照Priority属性值从大到小排序;Priority属性值相同者,动态注册的广播优先 。
下面是一个例子:
```java
// 广播接收器
private BroadcastReceiver mReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(mReceiver, filter);
```
如果某条广播被中断了,后面的广播接收器将无法收到广播 。
你可以使用以下代码来注册广播接收器:
```java
IntentFilter filter = new IntentFilter();
filter.addAction("你的action");
registerReceiver(new MyBroadcastReceiver(), filter);
```
如果你想要动态注册广播接收器,可以使用以下代码:
```java
Context context = getApplicationContext();
IntentFilter filter = new IntentFilter();
filter.addAction("你的action");
registerReceiver(new MyBroadcastReceiver(), filter);
context.registerReceiver(new MyBroadcastReceiver(), filter);
```
请根据提供的内容完成内容重构,并保持段落结构:
```xml
// 注册广播1
// 注册广播2
// 或者
mReceiver = new MyBroadcastReceiver();
mReceiver2 = new MyBroadcastReceiver2();
IntentFilter filter = new IntentFilter();
filter.addAction(“test”);
filter.setPriority(100);
registerReceiver(mReceiver, filter);
registerReceiver(mReceiver2, filter);
```
发送广播:
```java
Intent intent = new Intent();
intent.setAction(“test”);
sendOrderedBroadcast(intent, null);
```
有序广播的使用过程与普通广播非常类似,主要区别在于发送方式。在发送过程中,我们使用sendOrderedBroadcast方法来实现有序广播。要判断是否是有序广播,可以在onReceive方法中调用isOrderedBroadcast方法,如果返回true,则表示是有序广播。如果需要中断广播传递,可以在onReceive方法中调用abortBroadcast方法。
App应用内广播(Local Broadcast)是指在Android系统中,广播可以跨App(跨进程)直接通信。这是因为默认情况下,exported属性为true。然而,由于广播是根据发送意图Intent和意图过滤器Intent-filter进行匹配判断的,这可能会导致一些问题。例如,如果其他App发出来的广播Intent与当前App的Intent-filter相匹配,那么当前App就会不断接收并处理这个广播。如果不法分子知道了App的Intent-filter,就有可能通过此漏洞进行一些不良信息的推送,从而影响App的安全性。
为了解决这个问题,我们可以采取以下措施:
1. 将全局广播设置成局部广播:在注册广播时,将exported属性设置为false,这样非本App内部发出的此广播就不会被接收。
2. 增设权限验证:在广播发送和接收时,增加相应的权限permission,用于权限验证。例如:
```xml
```
通过以上方法,我们可以有效地防止恶意App通过发送匹配的广播Intent来推送不良信息,从而提高App的安全性。
、自定义新权限
在AndroidManifest.xml文件中添加自定义权限:
```xml
```
2、使用本地广播,系统封装好的LocalBroadcastManager类
首先,在接收器(MyBroadcastReceiver)中添加权限声明:
```java
import com.hzw.permission.MY_RECEIVER;
```
然后,在IntentFilter中设置action和priority:
```xml
android:permission="com.hzw.permission.MY_RECEIVER">
```
接下来,在发送方的Activity中使用LocalBroadcastManager进行广播:
```java
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
// 创建一个Intent对象,并设置action和传递数据(可选)
Intent intent = new Intent("test");
// intent.putExtra("key", "value"); // 如果需要传递数据,可以在这里添加
// 使用LocalBroadcastManager发送广播
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
```
```java
mReceiver2 = new MyBroadcastReceiver2();
IntentFilter filter = new IntentFilter();
filter.addAction("test"); // 获取LocalBroadcastManager类的实例,通过该实例注册广播
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mLocalBroadcastManager.registerReceiver(mReceiver2, filter); // 注销也需通过LocalBroadcastManager进行注销
mLocalBroadcastManager.unregisterReceiver(mReceiver2);
```
使用LocalBroadcastManager方式发送的应用内广播只能通过LocalBroadcastManager动态注册,不能静态注册。感谢以下链接提供的更多信息:https://blog.csdn.net/carson_ho/article/details/52973504 https://blog.csdn.net/javensun/article/details/7334230 http://h529820165.iteye.com/blog/1656778