Broadcast Receiver类型:
-
标准广播(无序广播):是一种完全异步执行的广播,在广播发出后,所有广播接收器几乎会同时接收到这个广播消息,因此没有先后顺序可言,这种广播的效率比较高,同时意味着无法截断.
-
有序广播:是一种同步执行的广播,在广播发出后,同一个时刻只有一个广播接收器能接收到,当这个广播接收器中的逻辑执行完广播才会传递.所有此时的广播接收器是由先后顺序的,优先级高的广播接收器可以先接收,并且前的广播接收器可以截断正在传递的广播,这样后面的广播接收器就无法接收信息.
动态注册
public class MainActivity extends AppCompatActivity {
private NetWorkChangeReceiver netWorkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netWorkChangeReceiver = new NetWorkChangeReceiver();
registerReceiver(netWorkChangeReceiver,intentFilter);
}
public class NetWorkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "网络发生了变化", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netWorkChangeReceiver);
}
}
静态注册
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name=".MainActivity.NetWorkChangeReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "开机完成", Toast.LENGTH_SHORT).show();
}
}
发送标准(无序)广播:
public void sendBroadcast(View view){
Intent intent=new Intent("android.intent.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
发送有序广播:
public void sendBroadcast(View view) {
Intent intent = new Intent("android.intent.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent, null);
}
本地广播:
public class MainActivity extends AppCompatActivity {
private LocalBroadcastManager localBroadcastManager;
private MyLocalReceiver localReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new MyLocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
}
public void sendLocalBroadcast(View view) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class MyLocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "本地广播", Toast.LENGTH_SHORT).show();
}
}
}
两者及其接收广播的区别:
-
动态注册广播不是常驻型广播,跟随Activity的生命周期。注意在Activity结束前,移除广播接收器。静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
-
当广播为有序广播时:优先级高的先接收(不分静态和动态)。同优先级的广播接收器,动态优先于静态
-
同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。**
-
当广播为默认广播时:无视优先级,动态广播接收器优先于静态广播接收器
LocalBroadcastManager源码阅读
为什么需要两个map呢?
private final HashMap<BroadcastReceiver, ArrayList<ReceiverRecord>> mReceiver = new HashMap<>();
private final HashMap<String, ArrayList<ReceiverRecord>> mActions = new HashMap<>();
-
注册广播的时候,根据receiver对象和action值(不是IntentFilter)分别进行了归类,存在了上述两个集合中。
-
发送广播的时候,先根据action值找出了所有对应的ReceiverRecord,然后再拿出ReceiverRecord存储的IntentFilter和Intent进行匹配,匹配上的取出其中的receiver,这个流程首先说明了mActions的存在意义,
mReceiver是为了方便取消注册时检索,而mActions是为了方便发送广播时检索。这也是Map相对于List在检索上的优势体现。
本地广播通过Handler来实现发送和分发的异步处理,我们还可以知道本地广播之所以不能跨进程、效率高是因为,其注册、分发等都是通过本地变量完成的,而不像全局广播那样通过binder机制实现。