1. 广播机制简介:
系统广播:
—— 跨进程,安全性比较低
本地广播:
—— 仅限本应用程序,安全性较高
Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应用程序的
系统全局广播:
接收系统广播 | 发送自定义广播 |
---|---|
动态注册接收器 | 发送标准广播 |
静态注册接收器 | 发送有序广播 |
动态注册:
直接在代码中注册
静态注册:
在 AndroidManifest.xml 中注册
标准广播:
是一种完全异步执行的广播,所有的广播接收器之间几乎没有任何先后顺序。这种广播效率会比较高,但同时它是无法截断的
有序广播:
是一种同步执行的广播,广播发出后,同一时刻只会有一个广播接收器接收到这条广播,这种广播有先后顺序,优先级高的接收器可以先收到广播,并且前面的接收器可以截断正在传递的广播
2. 接收系统广播:
动态注册监听网络变化:
- 定义一个 Receiver类 继承自 Broadcast-Receiver,并复写父类的
onReceive()
方法,调用addAction()
添加 action值,当网络状态发生变化时,系统发出的正式一条值为android.net.conn.CONNECTIVITY_CHANGE
的广播,想要监听什么广播便添加相应的 action值。最后,动态注册的接受器一定要取消注册
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){
Toast.makeText(context, "网络没毛病", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "网络不可用", Toast.LENGTH_SHORT).show();
}
}
}
}
- 在
onReceive()
方法中,通过getSystemService()
方法得到了 ConnectivityManager 的实例,这是一个系统服务类,专门用于管理网络连接。然后调用它的getActiveNetworkInfo()
方法可以得到 NetworkInfo 的实例,接着调用 NetworkInfo 的isAvailable()
方法即可判断当前是否有网络
—— 最后需要在 AndroidManifest.xml 中注册访问系统网络状态权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
静态注册实现开机启动:
- 使用 Android Studio 提供的快捷方式新建一个广播接收器,Exported 属性表示是否允许这个接收器接收本程序以外的广播,Enabled 属性表示是否启用这个接收器
- AndroidManifest.xml 中 Android Studio 已经自动注册好了静态的广播接收器,由于需要监听开机广播,因此需要声明接收开机广播权限,并且 <intent-filter> 标签也需要添加相应的 action值
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
—— 注:不要在 onReceive()
方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的
3. 发送标准广播和有序广播:
<intent-filter android:proprity="100">
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
—— AndroidManifest.xml 中接收器的 <intent-filter> 标签中可以添加自定义的 action,表示接收这种 action值 的广播。android:priority 属性可以设置接收器优先级
-
sendBroadcast(intent)
—— 表示发送标准广播 -
sendOrderedBroadcast(intent, null)
—— 表示发送有序广播 -
abortBroadcast()
—— 表示截断接收到的广播
4. 使用本地广播:
本地广播用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。另外,本地广播是无法通过静态注册的方式来接收的
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =
new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.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){
// 编写逻辑操作
}
}
}
网友评论