android 广播介绍
一 广播的分类
1.有序广播
有序广播是指广播发送后,广播接收器会根据优先级先后接收到发送的广播。
优点:先接收到广播的广播接收器可截断该广播,让优先级低的广播接收器接收不到该广播。
缺点: 广播效率低
2.标准广播
标准广播,也叫无序广播,是指广播发送后,广播接收器几乎在同一时间接收到该广播。
优点:广播效率高
缺点:广播无法被截断
二 广播的定义
广播的定义需要继承BroadcastReceiver类,重写里面的onReceive方法,也就是当接收到广播时需要做什么。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
}
}
三 广播的注册
1.静态注册广播
静态注册广播只需要在AndroidManifest.xml注册需要接收的广播即可。
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.stu.test"/>
</intent-filter>
</receiver>
该广播接收器能接收到关机广播以及一个自定义的广播。
注意:
2.动态注册
动态注册比静态广播注册复杂,静态注册只需要在AndroidManifest.xml注册就可以了,在应用安装时系统会自动注册完成该广播,而动态注册需要使用代码注册,不仅如此,还需要在合适的时机进行解注册。
MyReceiver myReceiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.BOOT_COMPLETED");
filter.addAction("com.stu.test");
registerReceiver(myReceiver,filter);
该广播接收器能接收到关机广播以及一个自定义的广播。
解注册:
unregisterReceiver(myReceiver)
四 广播的发送
广播的发送离不开intent,广播发送会根据intent是隐式还是显式分为隐式发送广播和显式发送广播。
1.显式intent
Explicit intents specify the component to start by name (the fully-qualified class name). You’ll typically use an explicit intent to start a component in your own app, because you know the class name of the activity or service you want to start. For example, start a new activity in response to a user action or start a service to download a file in the background.
显式intent明确了需要启动的组件的完整类名。
2.隐式intent
Implicit intents do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it. For example, if you want to show the user a location on a map, you can use an implicit intent to request that another capable app show a specified location on a map.
隐式intent不是指定需要启动的组件的完整类名,而是指定了执行的操作,由系统去过滤出与之相匹配的组件,然后启动,通常在不同的应用中使用。
1.发送显示广播
使用显式intent,eg:
Intent intent = new Intent("com.stu.test");
intent.setPackage("com.homework.stu");
//发送标准广播
sendBroadcast(intent);
//发送有序广播
sendOrderedBroadcast(intent);
2.发送隐式广播
使用隐式intent,eg:
Intent intent = new Intent("com.stu.test");
//发送标准广播
sendBroadcast(intent);
//发送有序广播
sendOrderedBroadcast(intent);
注意:通过静态注册的广播接收器,Android8.0及以上版本会出现隐式广播发送后没有被对应的广播接收器接收到,这是因为通过静态注册的广播接收器不会随组件的生命周期结束而结束,也就是说,只要应用中接收到静态注册的广播,应用就会被唤醒,为了优化系统性能,Android8.0及以上的设备对隐式广播做了限制,为了解决这一问题,可以通过intent的setPackage()或setComponent()方法指明包名将隐式intent转换成显式intent,还可以直接给隐式intent添加以下flag突破限制。
Intent intent = new Intent("com.stu.test");
//突破静态注册广播接收器接收隐式广播的限制
intent.addFlag(0x01000000);
//发送标准广播
sendBroadcast(intent);
//发送有序广播
sendOrderedBroadcast(intent);
注意:从Android3.1开始,系统为所有广播默认添加了FLAG_EXCLUDE_STOPPED_PACKAGES,为了防止注册了该广播的其他已经停止运行的应用因接收到这个广播而唤醒该应用。与之相反的是FLAG_INCLUDE_STOPPED_PACKAGES。这里应用停止运行有两种情况,一是应用安装后未运行。二是应用被手动或者其他应用强行停止了。
五 简单介绍粘性广播
粘性广播也叫等待广播,是指广播先发送,但是没有先注册广播去接收该广播,而是将该广播保存起来,过段时间再注册广播接收器,广播接收器会接收到该广播。
简单例子:
布局就是简单的两个按钮——注册广播按钮和发送粘性广播按钮
代码:
package com.homework.stu;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class StickyBroadcastActivity extends AppCompatActivity {
private final static String TAG = "StickyBroadcastActivity";
/*
* 广播接收器
*/
private BroadcastReceiver mBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sticky_broadcast);
//广播注册按钮
Button btnRegisterBroadcast = findViewById(R.id.btn_register_sticky_broadcast);
btnRegisterBroadcast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
IntentFilter filter = new IntentFilter();
filter.addAction("com.stu.stickyBroadcast");
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "接收广播时间:"+System.currentTimeMillis());
}
};
//动态注册广播
registerReceiver(mBroadcastReceiver,filter);
}
});
//广播发送按钮
Button btnSendBroadcast = findViewById(R.id.btn_send_sticky_broadcast);
btnSendBroadcast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "发送广播时间为: "+System.currentTimeMillis());
Intent intent = new Intent("com.stu.stickyBroadcast");
intent.setPackage("com.homework.stu");
//发送粘性广播——需要在AndroidManifest.xml中申请权限
sendStickyBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//解注册
unregisterReceiver(mBroadcastReceiver);
}
}
先点击发送广播按钮,再点击注册广播接收器
打印结果如下: