Localbroadcastmanager frequently used in-app communication components, also officially recommended in-app broadcast send components
at first, when using this component, the name is known, because Localbroadcast, so thought is also used binder to achieve the bottom, the result is not this.
1, usually we are so with LocalbroadcastmanagerA, register and receive
Localbroadcastmanager Broadcastmanager = localbroadcastmanager.getinstance (context); Intentfilter IntentFilter = new Intentfilter (); Intentfilter.addaction (ACTION), mreceiver = new Broadcastreceiver () {@Overridepublic void OnReceive ( Context context, Intent Intent) {String Key = Intent.getextras (). getString ("key"), if ("Key". Equals (Key)) {log.i ("tag", " Receive the broadcast ");}}; Broadcastmanager.registerreceiver (Mreceiver, Intentfilter);
b. Send broadcast
Localbroadcastmanager.getinstance (context). Sendbroadcast (New Intent (ACTION));
c. Cancellation of registration
Localbroadcastmanager.getinstance (context). Unregisterreceiver (Mreceiver);
2, how to achieve? A, asynchronous to the source:Localbroadcastmanager.java See how it is implemented in the end, the standard single-instance implementation:
static final int msg_exec_pending_broadcasts = 1; 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 = new Handler (Context.getmainlooper ()) {@Override public void Handlemessage (Message msg) { Switch (msg.what) {case Msg_exec_pending_broadcasts:executepen Dingbroadcasts (); Break Default:super.handleMessage (msg); } } }; }
a new instantiation of the Looper (Context.getmainlooper ()) based on the main thread calls the receiver to process the broadcast message in a Handler,handlemessage method.
B, registered to receive
/** * 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 (Broadcastreceiver receiver, Intentfilter filter) { Synchronized (mreceivers) {Receiverrecord entry = new Receiverrecord (filter, receiver); arraylist<intentfilter> filters = mreceivers.get (receiver); if (filters = = null) {filters = new arraylist<intentfilter> (1); Mreceivers.put (receiver, filters); } filters.add (filter); 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); } } }registers the storage broadcast and filtering information to Broadcastreceiver to Key,intentfilter as value and stores it to ArrayList.
here Mreceivers, why the saved Intentfilter is ArrayList form, the Intentfilter is able to save multiple action, which is why he initialized to a 1-length list. The ArrayList here can pass in multiple intentfilter, though, but if the action is the same, it will come out as one. The action is stored as a key.
c. Cancellation of registration
/** * Unregister a previously registered broadcastreceiver. <em>All</em> * Filters that has been registered for this broadcastreceiver would be is * removed. * * @param receiver the broadcastreceiver to unregister. * * @see #registerReceiver */public void Unregisterreceiver (Broadcastreceiver receiver) {synchronized (mreceivers) {Arraylist<intentfilter> filters = mreceivers.remove (receiver); if (filters = = null) {return; } for (int i=0; i<filters.size (); i++) {Intentfilter filter = Filters.get (i); for (int j=0; j<filter.countactions (); j + +) {String action = filter.getaction (j); arraylist<receiverrecord> receivers = Mactions.get (action); if (receivers! = null) {for (int k=0; k<receivers.size (); k++) {if (RECEIVERS.GET (k). Receiver = = receiver) {receivers.remove (k); k--; }} if (Receivers.size () <= 0) {Mactions.remo ve (action); } } } } } }just remove the corresponding elements from Mreceivers and mactions.
D, should look at this time executependingbroadcasts () method source code:
private void Executependingbroadcasts () { while (true) { broadcastrecord[] BRs = null; Synchronized (mreceivers) { final int N = Mpendingbroadcasts.size (); if (N <= 0) { return; } BRS = new Broadcastrecord[n]; Mpendingbroadcasts.toarray (BRS); Mpendingbroadcasts.clear (); } for (int i=0; i<brs.length; i++) { Broadcastrecord br = brs[i]; for (int j=0; j<br.receivers.size (); j + +) { br.receivers.get (j). Receiver.onreceive (Mappcontext, br.intent); } } } }
This function, mpendingbroadcasts to broadcastrecord[], loops through each receiver, invokes broadcast's OnReceive function, and completes the broadcast logic. Message processing is complete.
e, how to send the broadcast
/** * Broadcast the given intent to all interested broadcastreceivers. This * call is asynchronous; It returns immediately, and you'll continue * executing while the receivers is run. * * @param intent the intent to broadcast; All receivers matching this * Intent would receive the broadcast. * * @see #registerReceiver */public boolean sendbroadcast (Intent Intent) {synchronized (mreceivers) { Final String action = Intent.getaction (); Final String type = intent.resolvetypeifneeded (Mappcontext.getcontentresolver ()); Final Uri data = Intent.getdata (); Final String scheme = Intent.getscheme (); Final set<string> categories = Intent.getcategories (); Final Boolean debug = Debug | | ((Intent.getflags () & intent.flag_debug_log_resolution)! = 0); if (Debug) log.v (TAG, "Resolving type" + Type + "SCHeme "+ scheme +" of intent "+ intent); arraylist<receiverrecord> entries = Mactions.get (intent.getaction ()); if (entries! = null) {if (debug) log.v (TAG, "Action list:" + entries); arraylist<receiverrecord> receivers = NULL; for (int i=0; i<entries.size (); i++) {Receiverrecord receiver = entries.get (i); if (Debug) log.v (TAG, "Matching against filter" + receiver.filter); if (receiver.broadcasting) {if (debug) {log.v (TAG, "Filter ' s target Already added "); } continue; } int match = Receiver.filter.match (action, type, scheme, data, categories, "Localbroadcastmanager"); if (match >= 0) {if (debug) log.v (TAG, "Filter matched! match=0x "+ integer.tohexstring (match)); if (receivers = = NULL) {receivers = new arraylist<receiverrecord> (); } receivers.add (receiver); Receiver.broadcasting = true; } else {if (debug) {String reason; Switch (match) {case IntentFilter.NO_MATCH_ACTION:reason = "ACTION"; Case IntentFilter.NO_MATCH_CATEGORY:reason = "CATEGORY"; Break Case IntentFilter.NO_MATCH_DATA:reason = "DATA"; Break Case IntentFilter.NO_MATCH_TYPE:reason = "TYPE"; Break Default:reason = "Unknown Reason"; Break } log.v (TAG, "Filter didNot match: "+ reason); }}} if (receivers! = null) {for (int i=0; i<rece Ivers.size (); i++) {receivers.get (i). Broadcasting = FALSE; } mpendingbroadcasts.add (New Broadcastrecord (intent, receivers)); if (!mhandler.hasmessages (msg_exec_pending_broadcasts)) {Mhandler.sendemptymessage (Msg_exec_pendin g_broadcasts); } return true; }}} return false; }
Remove the Receiverrecord list from mactions according to action, looping through each Receiverrecord to determine the action\type\scheme\data\ in the filter Categoried whether match, matches the words to save to receivers, then sends the empty message, what=msg_exec_pending_broadcasts, this time handler will go to deal with.
Summary:A, registration and anti-registration consistency, OnStart, OnStopB, a broadcast, it is best to put the action in a intentfilter. C, Localbroadcastmanager only the registration to the role of interaction. D, the core of Localbroadcastmanager is handler, using the match function of Intentfilter. E, handler implementation of intra-code communication, he holds broadcastreceiver objects, directly call the OnReceive method, security efficiency high.
Secret Localbroadcastmanager Implementation principle