广播说明
- 系统全局广播机制
可以跨进程通信的方式,比如说系统广播任何应用都能接收到,所以我们应用程序中发的广播,其他应用也可以收到。 - 本地广播机制
系统全局广播存在不安全性,所以安卓还提供了一套本地广播机制。
系统全局广播机制
广播类型
标准广播
是一种完全异步执行的广播,广播发出后,所有的接收器几乎都会在同一时间接收到这条广播,效率高,但无法被截断。
有序广播
同步执行的广播,同一时刻,只有一个广播接收器能够接受,直到接收器中逻辑处理完成,才能向下传递。有先后顺序,优先级高的接收器先接收到,并且接收到后可以进行拦截。
广播的使用
广播的接收
动态注册接收
- 优点:能够自由的控制注册和注销
- 缺点:必须在程序启动之后才能启动
代码示例
public class BroadcastReceiverActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private ActiveBroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brodcast_receiver);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
receiver = new ActiveBroadcastReceiver();
registerReceiver(receiver, intentFilter); //注册广播
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);//注销广播
}
class ActiveBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "收到了广播", Toast.LENGTH_SHORT).show();
}
}
}
静态注册接收
第一步 :写一个广播接受者
代码示例
public class StaticReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "接收到发出的广播", Toast.LENGTH_SHORT).show();
}
}
第二步:去清淡文件注册这个广播接受者写着 中
第三步:使用,写了一个定时任务去发起这个广播
public class BroadcastReceiverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brodcast_receiver);
android.app.AlarmManager manager = (android.app.AlarmManager) getSystemService(ALARM_SERVICE);
int time = 5 * 1000;//5秒钟发一个广播
long triggerAtTime = SystemClock.elapsedRealtime() + time;
Intent i = new Intent(this, StaticReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
manager.set(android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
}
}
广播的发送
发送标准广播
第一步:创建一个广播接受者
public class StandardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "StandardReceiver收到了广播", Toast.LENGTH_SHORT).show();
}
}
第二步:在清单文件中注册广播,添加过滤action
第三步:发送广播
public class BroadcastReceiverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brodcast_receiver);
Intent intent = new Intent();
//此处和清淡文件中的action同,且程序中添加了这个action的广播接受者,都能接收到。其他程序也能接收。
intent.setAction("com.tomato.mystandardBroadcast");
sendBroadcast(intent);
}
}
发送有序广播
第一步:创建一个广播接受者
public class OrderlyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "StandardReceiver收到了广播", Toast.LENGTH_SHORT).show();
abortBroadcast();//拦截收到的广播,不然再往下传递
}
}
第二步:清单文件注册,并设置优先级
第三步:发送有序广播
public class BroadcastReceiverActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brodcast_receiver);
Intent intent = new Intent();
//此处和清淡文件中的action同,且程序中添加了这个action的广播接受者,都能接收到。其他程序也能接收。
intent.setAction("com.tomato.mystandardBroadcast");
//发送有序广播
sendOrderedBroadcast(intent, null);
}
}
本地广播机制
优点
- 只能在内部进行传递,正在发送的广播不会离开我们的程序,不用担心数据安全
- 接收器只能接收本程序的广播,其他程序无法将广播发送到我们广播内部,不存在安全漏洞
- 比全局广播更高效
注意点
- 无法通过静态注册来接收。
使用
public class BroadcastReceiverActivity extends AppCompatActivity {
private LocalBroadcastManager manager;
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brodcast_receiver);
manager = LocalBroadcastManager.getInstance(this);
initReceiver();
sendBroadcast();
}
/**
* 发送本地广播
*/
private void sendBroadcast() {
Intent intent = new Intent();
intent.setAction("com.tomato.testLocalBroadcast");
manager.sendBroadcast(intent);
}
/**
* 注册广播接受者
*/
private void initReceiver() {
intentFilter = new IntentFilter();
intentFilter.addAction("com.tomato.testLocalBroadcast");
localReceiver = new LocalReceiver();
manager.registerReceiver(localReceiver, intentFilter);
}
/**
* 注销广播接受者
*/
@Override
protected void onDestroy() {
super.onDestroy();
manager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到本地广播", Toast.LENGTH_SHORT).show();
}
}
}
实践:强制下线功能
实现思路:
- 收到强制下线的消息时,发送一条广播
- 创建一个下线广播接收器
- 在onReceiver中弹出强制下线弹出框
- 在baseactivity的onResume方法中动态注册这个广播接收器
- 在baseActivity的onPause方法中注销这个广播接收器(只有在栈顶的activity才处理这个广播,所以选择在这两个方法里注册和注销)