1. 广播机制
标准广播: 是一种完全异步执行的广播,在广播发出后几乎所有的接收器都会在同一时刻受到广播消息。因此它们之间没有任何的先后顺序,这种广播效率比较高,但同时意味着不能被截断。
有序广播: 是一种同步执行的广播,在广播发出后,同一时刻只有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后广播才会继续传播。有序广播是有先后顺序的,优先级高的会优先接受到广播并且可以截断正在传递的广播。
2. 接收系统广播
2.1 动态监听
动态监听网络变化
新建一个类,让他继承 BoradcastReceiver 并重写 onReceive() 方法,当接受到广播后就会执行 onReceive() 方法,这样一个简单的广播接收器就创建好了。
public class NetChangeActivity extends AppCompatActivity {
NetWorkChangeReceiver netWorkChangeReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ui);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netWorkChangeReceiver = new NetWorkChangeReceiver();
registerReceiver(netWorkChangeReceiver,intentFilter);
}
class NetWorkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"网络状态发生变化",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netWorkChangeReceiver);
}
}
步骤:
- 新建一个广播接收器
- 通过 IntentFilter 来指定要接收的广播
- registerReceiver() 来注册广播
- 动态注册的广播接收器一定要取消注册
2.2 静态监听
静态监听实现开机自启
动态监听的缺点:动态注册的广播必须在程序启动后才能接收广播。
静态注册可以让程序没有启动就接受到广播消息。
首先我们新建一个 Java 类继承自 BroadcastReceiver
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"开机完成",Toast.LENGTH_SHORT).show();
}
}
<application>
<receiver android:name="com.example.firstcode.fifty_chapter.bootreceiver.BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
- exported 为 true 表示可以接收本程序之外的广播。
- enable 的意思就是启用这个广播接收器。
广播接收器 onReceive() 方法里面不要做太多的逻辑或者任何的耗时操作,因为在广播接收器中是不允许开启线程的,并且如果 onReceive() 方法运行了较长时间而没有结束的话程序就会报错。因此广播接收器扮演的是一种打开程序其他组件的角色,比如创建状态栏通知,或者启动一个服务等等。
3. 发送自定义广播
3.1 发送标准广播
首先需要定义一个广播接收器,与上类似,此处不在累述。
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
调用 context 的 sendBroadcast 即可发送广播,也可以通过 intent 携带数据。
3.2 发送有序广播
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent, null);
为广播接收器定义优先级,优先级高的先接收到广播
<application>
<receiver
android:name="com.example.firstcode.BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
截断广播,不让广播继续传递
public class MyBroadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"",Toast.LENGTH_SHORT).show();
// 截断广播
abortBroadcast();
}
}
3.3 有序广播权限用法
谁有权接受我的广播
发送者
sendOrderedBroadcast(intent, "com.android.permission.yourdiyname");
AndroidManifest.xml 中声明权限, 注意要和上面的对应上
<permission android:name="com.android.permission.yourdiyname" />
接收者
AndroidManifest.xml中声明权限 注意要和上面对应上
<uses-permission android:name="com.android.permission.yourdiyname" />
只有全部对应上接收者才会接收到广播
谁有权给我发送广播
发送者
<uses-permission android:name="com.android.permission.yourdiyname" />
接收者
<permission android:name="com.android.permission.yourdiyname" />
<receiver android:name=".YourDiyReceiver"
android:permission="com.android.permission.yourdiyname">
<intent-filter>
<action android:name="com.android.YOUR_DIY_ACTION" />
</intent-filter>
</receiver>
4. 本地广播
本地广播机制使发出的广播只能在程序内部传递,并且广播接收器也只能接收来自本程序的广播,主要利用 LocalBriadcastManager 来对广播进行管理。
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 = (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) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
- 通过
LocalBroadcastManager.getInstance(this);
获取实例 localBroadcastManager.sendBroadcast(intent);
发送本地广播localBroadcastManager.registerReceiver(localReceiver, intentFilter);
注册本地广播接收器