https://www.jianshu.com/p/ca3d87a4cdf3
LocalbroadcastManager 实现原理初始化LocalbroadcastManager采用的是Handler的消息机制来处理的广播,而注册到系统中的是通过Binder机制实现的,速度是应用内广播要快很多。不过由于Handler的消息机制是为了同一个进程的多线程间进行通信的,因而跨进程时无法使用应用内广播。
LocalbroadcastManager 采用的是单例模式,并且在私有的构造函数中创建了一个mHandler,该Handler关联的是主线程的Looper。所以消息的处理都是在主线程中处理的。
private final Handler mHandler; private static final Object mlock = new Object(); private static LocalbroadcastManager mInstance; public static LocalbroadcastManager getInstance(Context context) { synchronized (mlock) { if (mInstance == null) { mInstance = new LocalbroadcastManager(context.getApplicationContext()); } return mInstance; } } private LocalbroadcastManager(Context context) { mAppContext = context; //mHandler是主线程的 mHandler = new Handler(context.getMainLooper()) { @OverrIDe public voID handleMessage(Message msg) { switch (msg.what) { case MSG_EXEC_PENDING_broADCASTS: executePendingbroadcasts();//这里去执行广播分发 break; default: super.handleMessage(msg); } } }; }
注册广播registerReceiver /** * Register a receive for any local broadcasts that match the given IntentFilter. * * @param receiver The broadcastReceiver to handle the broadcast. * @param filter Selects the Intent broadcasts to be received. * * @see #unregisterReceiver */ public voID registerReceiver(@NonNull broadcastReceiver receiver, @NonNull IntentFilter filter) { synchronized (mReceivers) { ReceiverRecord entry = new ReceiverRecord(filter, receiver); ArrayList<ReceiverRecord> filters = mReceivers.get(receiver); if (filters == null) { filters = new ArrayList<>(1); mReceivers.put(receiver, filters); } filters.add(entry); for (int i=0; i<filter.countActions(); i++) { String action = filter.getAction(i); ArrayList<ReceiverRecord> entrIEs = mActions.get(action); if (entrIEs == null) { entrIEs = new ArrayList<ReceiverRecord>(1); mActions.put(action, entrIEs); } entrIEs.add(entry); } } }
会将 Receiver 和action 存在下方的数据结构中
private final HashMap<broadcastReceiver, ArrayList<ReceiverRecord>> mReceivers = new HashMap<>(); private final HashMap<String, ArrayList<ReceiverRecord>> mActions = new HashMap<>();
unregisterReceiver /** * Unregister a prevIoUsly registered broadcastReceiver. <em>All</em> * filters that have been registered for this broadcastReceiver will be * removed. * * @param receiver The broadcastReceiver to unregister. * * @see #registerReceiver */ public voID unregisterReceiver(@NonNull broadcastReceiver receiver) { synchronized (mReceivers) { final ArrayList<ReceiverRecord> filters = mReceivers.remove(receiver); if (filters == null) { return; } for (int i=filters.size()-1; i>=0; i--) { final ReceiverRecord filter = filters.get(i); filter.dead = true; for (int j=0; j<filter.filter.countActions(); j++) { final String action = filter.filter.getAction(j); final ArrayList<ReceiverRecord> receivers = mActions.get(action); if (receivers != null) { for (int k=receivers.size()-1; k>=0; k--) { final ReceiverRecord rec = receivers.get(k); if (rec.receiver == receiver) { rec.dead = true; receivers.remove(k); } } if (receivers.size() <= 0) { mActions.remove(action); } } } } } }
总结优点:
1:相对于串行广播,更加安全,数据只会在应用内部传输,并且限定在同一进程中,一个APK中其他的进程也是不行的
2:性能较好:相对于串行广播,其不对system_server造成任何的性能问题,并且也没有跨进程调用带来的耗时问题
缺点:
1:不支持跨进程,如果跨进程必须考虑其他实现方式
2:不支持静态xml的方式注册,无法实现监听诸如系统开机广播等
以上是内存溢出为你收集整理的Android四大组件:BroadcastReceiver史上最全面解析全部内容,希望文章能够帮你解决Android四大组件:BroadcastReceiver史上最全面解析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)