零:参考
一、广播接收者
(一)定义
用于接收广播的组件,用于组件与组件之间进行通信,可以跨应用程序传递。
- 注意:广播接收器运行在UI线程。
- 优点:很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。
(二)创建、注册
1. Broadcast Receiver的创建
- 继承BroadcastReceiver类,并实现其onReceive 方法。
- 在onReceive方法内,我们可以获取随广播而来的Intent中的数据,这非常重要,就像无线电一样,包含很多有用的信息。
- 代码演示:
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
}
}
2. Broadcast Receiver的注册
- 在创建完BroadcastReceiver之后,还不能够使它进入工作状态,需要为它注册一个指定的广播地址。
- 没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。
(1)静态注册
- 方式:在AndroidManifest.xml里通过< receiver >标签声明。
- 特点:
- App首次启动时,系统会自动实例化MyBroadcastReceiver类,并注册到系统中。
- 常驻进程中,不受组件生命周期影响,就算组件生命周期结束后,还有广播发送过来,还是会被唤醒调用。
- 应用场景:需要时刻监听广播。
- 代码演示:
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot complete", Toast.LENGTH_LONG).show();
}
}
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
...
<receiver
android:name=".broadcast.BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
(2)动态注册
- 方式:在代码中调用Context.registerReceiver()方法。
- 特点:跟随组件的生命周期变化,如果组件生命周期结束了,广播就必须结束,否则会产生内存泄漏。
- 应用场景:需要在特定时刻接收广播接收广播。
- 代码演示:
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcast";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: ");
Toast.makeText(context, "received in MyBroadcast", Toast.LENGTH_SHORT).show();
}
}
public class BroadcastActivity extends AppCompatActivity {
MyBroadcastReceiver mBroadcast;
@Override
protected void onResume() {
super.onResume();
mBroadcast = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CONNECTIVITY_SERVICE);
registerReceiver(mBroadcast, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mBroadcast);
}
}
- 注意:在onResume()中注册和在onPause()中注销的原因:防止内存泄漏(某些场景中,onStop()不会被调用)。
(三)优先级
- 优先级的范围:-2147483647到2147483647
- 优先级的长度范围:Integer类型数据的最大值4294967296(2的32次方)。
(四)应用
- 应用场合:发送频率低的情况可以使用,数据量小的情况可以使用。
- 实际应用:
- 操作系统电池电量低会发送一个广播,这样我们的程序里面可以去监听这个广播,可以关闭程序里面比较耗电的功能,提示用户注意保存进度;
- 安装新应用;
- 普通应用程序,例如启动特定线程,文件下载完毕等。
二、广播发送者
(一)发送方式
通过“意图(Intent)”的sendBroadcast()方法发送出去。
(二)广播类型
- 普通广播(Normal Broadcast)
- 系统广播(System Broadcast)
- 有序广播(Ordered Broadcast)
- 本地广播(Local Broadcast)
1. 普通广播
- 开发者自身定义 intent的广播,通过Context.sendBroadcast(Intent intent)发送,可以同时被所有广播接收者无需等待的接收到。
优点:异步、无差别接收、效率高。 - 代码演示:
public class MyBroadcast extends BroadcastReceiver {
private static final String TAG = "MyBroadcast";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: ");
Toast.makeText(context, "received in MyBroadcast", Toast.LENGTH_SHORT).show();
}
}
<receiver
android:name=".broadcast.MyBroadcast"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name=".broadcast.MY_BROADCAST" />
</intent-filter>
</receiver>
public class MyBroadcastActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast);
Button button = findViewById(R.id.btn_broadcast);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =new Intent();
intent.setComponent(new ComponentName( "com.example.first.broadcast" ,
"MyBroadcast") );
intent.setAction("com.example.first.broadcast.MY_BROADCAST");
sendBroadcast( intent );
}
});
}
}
2. 系统广播
- 只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),基本上都会发出相应的系统广播。每个系统广播都具有特定的intent-filter,其中主要包括具体的action,系统广播发出后,将被相应的BroadcastReceiver接收。
- 系统广播在系统内部当特定事件发生时,由系统自动发出。当使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播。
3. 有序广播
- 通过Context.sendOrderedBroadcast(intent, receiverPermission)发送,按照接收者声明的优先级别,被接收者依次接收广播。
- 广播接受者接收广播的顺序规则(同时面向静态和动态注册的广播接受者)
- 首先按照Priority属性值从大→小排序;
- Priority属性相同者,动态注册的广播优先。
- 优点:
- 广播可以通过接收者调用abortBroadcast()方法截断广播(被截断的广播不能再继续传递该广播)。
- 接收者能修改处理结果(比如通过传递Bundle)传递给下一个接收者(一般情况下,不建议对有序广播进行此类操作,尤其是针对系统中的有序广播)。
- 缺点:消息传递的效率比普通广播低。
4. 本地广播
- 使用LocalBroadcastManager来发送广播以及注册广播接收器。
- 优点:安全。它发出的广播只会在应用程序的内部传播,不用担心广播被其他应用接收,造成数据泄漏,而广播接收器也只能接收到自己应用发出的广播,不会接收别的应用发来的广播,防止接收垃圾信息。
- 本地广播无法通过静态注册方式接收。
public class LocalBroadcastActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_local_broadcast);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = findViewById(R.id.btn_local_broadcast);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.first.broadcast.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.first.broadcast.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
(三)部分系统广播常量
系统操作 | action |
---|
监听网络变化 | android.net.conn.CONNECTIVITY_CHANGE |
屏幕被关闭 | Intent.ACTION_SCREEN_OFF |
屏幕被打开 | Intent.ACTION_SCREEN_ON |
屏幕锁屏 | Intent.ACTION_CLOSE_SYSTEM_DIALOGS |
关闭或打开飞行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
充电时或电量发生变化 | Intent.ACTION_BATTERY_CHANGED |
电池电量低 | Intent.ACTION_BATTERY_LOW |
电池电量充足 | Intent.ACTION_BATTERY_OKAY |
插上外部电源时发出的广播 | Intent.ACTION_POWER_CONNECTED |
已断开外部电源连接时发出的广播 | Intent.ACTION_POWER_DISCONNECTED |
关闭或打开飞行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
系统启动完成后 | Intent.ACTION_BOOT_COMPLETED |
按下照相时的拍照按键(硬件按键)时 | Intent.ACTION_CAMERA_BUTTON |
插入耳机时 | Intent.ACTION_HEADSET_PLUG |
成功安装APK | Intent.ACTION_PACKAGE_ADDED |
成功删除APK | Intent.ACTION_PACKAGE_REMOVED |
重启设备 | Intent.ACTION_REBOOT |
关闭系统时 | Intent.ACTION_SHUTDOWN |
改变输入法时发出的广播 | Intent.ACTION_INPUT_METHOD_CHANGED |
设备当前区域设置已更改时发出的广播 | Intent.ACTION_LOCALE_CHANGED |
时间被设置时发出的广播 | Intent.ACTION_TIME_CHANGED |
时区发生改变时发出的广播 | Intent.ACTION_TIMEZONE_CHANGED |
设备日期发生改变时会发出此广播 | Intent.ACTION_DATE_CHANGED |
三、消息推送
- 推送选择:极光推送
- 推送集成