5 - 4 - BroadcastReceiver - Part 2 (16-24)

7
[BLANK_AUDIO]. Hi, I'm Adam Porter and this is Programming Mobile Applications for Android Handheld Systems. Now, after an intent is broadcast it will eventually be delivered to the appropriate broadcast receiver, through a call to be broadcast receivers onReceive method. And this method has two parameters. One, the context in which the receiver is running. And two, the intent that was broadcast. So there's some things to consider when you're writing the code that handles incoming broadcasts. First, to deliver a broadcast, Android may have to start a receiver's application process, because it might not actually be running when the intent is broadcast, and while on receive is running, that process has high priority. So broadcasting an intent, especially if it goes to multiple applications, can be a relatively expensive operation. Second, the onReceive method runs in the main thread of its hosting process, and like anything that you do on the main thread it should be fairly short lived and it shouldn't block the main thread. In particular if the processing you need to do in response to the broadcast is time consuming, then you should consider starting a service to do that work rather than doing the work in onReceive. In fact, that's exactly what the MMS application does when an MMS message arrives. A broadcast receiver receives a broadcast informing it that the MMS message has arrived. And in its onReceive method, when it gets called, it immediately passes the message to another service that handles all the work of downloading the message, storing it in a database and so forth. Of course, we haven't talked about services much yet, but we'll get to them in later lessons. A last issue to consider is that a broadcast receiver is considered valid only as long as

Transcript of 5 - 4 - BroadcastReceiver - Part 2 (16-24)

[BLANK_AUDIO].Hi, I'm Adam Porter and this isProgramming Mobile Applications forAndroid Handheld Systems.Now, after an intent is broadcast it willeventually be delivered to the appropriatebroadcast receiver, through a call to bebroadcast receivers onReceive method.And this method has two parameters.One, the context in which the receiver isrunning.And two, the intent that was broadcast.So there's some things to consider whenyou're writing the code that handlesincoming broadcasts.First, to deliver a broadcast, Android mayhave to start a receiver's applicationprocess, because it might notactually be running when the intent isbroadcast, andwhile on receive is running, that processhas high priority.So broadcasting an intent, especially ifit goesto multiple applications, can be arelatively expensive operation.Second, the onReceive method runs in themain thread of its hosting process, andlikeanything that you do on the main thread itshouldbe fairly short lived and it shouldn'tblock the main thread.In particular if the processing you needtodo in response to the broadcast is timeconsuming,then you should consider starting aservice to dothat work rather than doing the work inonReceive.In fact, that's exactly what the MMSapplication does when anMMS message arrives.A broadcast receiver receives a broadcastinformingit that the MMS message has arrived.And in its onReceive method, when it getscalled, it immediately passes the messageto another servicethat handles all the work of downloadingthemessage, storing it in a database and soforth.Of course, we haven't talked aboutservices much yet, but we'll get to themin later lessons.A last issue to consider is that abroadcast receiveris considered valid only as long as

OnReceive is running.In fact, once onReceive returns, Androidwill sometimes terminate the underlyingbroadcast receiver.In particular, this, this means thatbroadcast receivers can't start upoperations that will need to call back tothe receiver asynchronouslyat a later time.And of course, that makes sense becausethere's no guarantee thatthe broadcast receiver will even existwhen that call back occurs.Now examples of these asynchronouscallbacks include things like starting adialogue, or starting an activity via thestart activity or result method.So,let's look at some more examples ofapplications that use broadcast receivers.Here, I'll start up the compound broadcastapplication.It has a button labeled Broadcast Intent,which when pressedwill use the send broadcast method tobroadcast a show toast intent.This time, however, there are threebroadcast receivers that will receive thisintent.So nowI'll press the button.And below you see a toast message fromreceiver one, asecond one from receiver two, and thethird one from receiver three.Because the compound broadcast applicationusedsend to broadcast, the broadcasts weresentout normally and that means thatthe arrival and processing order wereundefined.In this case, the broadcast happened to behandled in one particular order.In other cases or on a different deviceor if Android changes in the future, thatordermight be different.So if you really want the broadcastreceivers to receive broadcastin a particular order, or if you want eachbroadcast receiverto have exclusive access to the intentwhile it's being processed,then you'll want to broadca, you'll wantthe broadcast to be ordered.And to, you'll do that by using a sendordered broadcast method.Andyou can do that using some of the methods,

some of the following methods from thecontext class.The first sends an intent to broadcastreceiversthat have a specified permission inpriority order.The second does the same thing,but provide additional parameters forgreater control.Let's look at some applications that usethese methods to send ordered broadcasts.Here, I'll start up the compound orderedbroadcast application.This application displays a button,labeled Broadcast Intent.And when you press the button a show toastintent is broadcast.For this application there are threeregistered broadcast receivers, of typereceiverone, receiver two and receiver three.And each of these has a differentpriority for receiving the broadcast.Receiver two has the highest priority,receiver one the next highest, andreceiver three has the lowest priority.So we expect the receivers to get thebroadcast in that order.Receiver two, receiver one, receiverthree.However, I put in some code, I put somecode in receiver one thataborts the broadcast.So in this case only receiver two andthen receiver one should receive thebroadcast.So let's see that in action.Now, I'll press the broadcast intentbutton andyou can see a toast message saying thatthe intent was received by receiver two,andthen another saying it was received byreceiver one.And apparently, poor receiver three getsleftout in the cold.Let's look at the source code for thisapplication.Now here I've got the application open inthe IDE.And I'll start by opening up the Androidmanifest.XML file.And as you can see I statically registeredreceiver two with a priority of ten.And receiver three I've registered with apriority of one.Nowback in the main activity, the codecreates an instance of

Receiver1, then creates an intentFilterfor the showtoast intent and then sets the priority tothree.So any Receiver2 instance has priorityten.This Receiver1 instance has prioritythree,and any receiver three instance haspriority one.Now, when the broadcast intent button ispressed, the listener calls sendordered broadcast, passing in a new showtoast intent.This intent is first received by areceiver two instance, andthen by a receiver one instance that wascreated in this file.Let's open the receiver one code.Now here in on receive you see that thecode checks to see whether this is anordered broadcast.And if so, it calls abort broadcast, whichconsumes thebroadcast, and in this case, prevents itfrom being sent on to receiver three.Now let's also look at a slightly morecomplicated use of ordered broadcast.In this application, called OrderedBroadcast with Result Receiver,we'll see that a single toast message isdisplayed, thatshows all the broadcast receivers thatreceive this intentand that indicates the order in which theyreceived it.Now here,I'll start the application.Now I'll press it's Broadcast Intentbutton and there's the toast message.It shows that receiver two received theintent, then receiverone, then receiver three.Let's look at the source code.Now here's the application open in theIDE.Now, I'll open the main activity and goto the listener for the broadcast intentbutton.Asyou can see, this code uses the secondform of the send broadcast method.One of the interesting parameters of thismethod isa broadcast receiver, I'll call it theresult receiverthat will receive the intent after all theotherbroadcast receivers have gotten theirchance to receive it.

This is useful if the initial broadcastreceivers compute some result.Because that result will then be availableto this last receiver, and it can getthat result by calling get result data, aswe see here.Now let's take a look at one of thebroadcast receiver classes to seehow they compute the result that thisresult receiver finally displays in thetoast message.Now, here's the receiver one class.And as you can see, it's on receivemethod, calls get result data, to get thecurrent result data.And then it tacks on its own string at theend.And then saves the new string by callingset result data, nowsince all the broadcast receivers do thisin turn, the finalresult data is a single string showingwhich receivers receivedthe intent, and the order in which theyreceived it.Thelast kind of broadcasts I'll talk abouttoday are sticky broadcasts.As I said earlier, non-sticky broadcastsindicate thatsomething's happened at the specificmoment in time.They announce events.So once the event is over, it's over.Android disposes of the event and moveson.If a broadcast receiver wasn't registeredto receive an intent whenit happened, say yesterday, then itshouldn't be told about it now.Because, for example, it might think thatthe event just happened.And that could lead to all kinds of timingproblems and other difficulties.Other events however, indicate statechanges that may persist over time.Broadcast receivers that want to knowaboutthe current device state, for example,will stillwant that information even if they weren'tregisteredto be notified when that particular statechanged.For example, if the battery level goesverylow Android will broadcast this fact tothe system.Good applications will want to be gooddevice citizen and

not do battery consuming operations whenthe device is in this low state.So in this case, if a new applicationstarts up and registers to hear about thebatterystate, that application needs to knowright nowif the device is in the low battery state.And because of this, Android broadcaststhat battery low intent asa sticky broadcast, so sticky intents arecached by Android,and sticky broadcasts of a given intentoverwrite any cachedvalues from previous sticky broadcasts ofa matching intent.When a broadcast receiver is dynamicallyregistered, anycached intents that match its intentfilter willbe broadcast to it.In addition, one matching cached intentwillbe returned to the caller of registeredreceiver.Now similar to what we saw with non-stickybroadcasts, stickybroadcasts can be sent normally, that iswithout a defined order, orsequentially, in priority order.Normal sticky broadcasts canuse this method.And ordered sticky broadcastscan use this method.And finally, applications that want tobroadcast sticky intents must have thebroadcast_sticky permission.Let's look at an example application thatuses sticky broadcasts.Now here, I'll run the sticky intentapplication in the emulator.I've also openeda terminal window, and started a Telnetsession with that emulator.Now, I'll start the application, whichdisplays the current battery level, anddisplays thestring, reading may be stale.And this last string justindicates that the battery level readingcomes froma cached, sticky broadcast, not from afresh broadcast.If I now go to the terminal window andchange the batterylevel, a new intent will be broadcastreflecting the updated battery level.So now I'll type power capacity 95 andhit return.As

you can see the display has been updated.And that display text has changed toindicate that broadcastreceiver can distinguish between freshbroadcasts and a cached one.Let's look at the source code for thisapplication.Nowhere I'm in the IDE.And now I'll open the main activity forthis application.It calls register receiver and passes in abroadcast receiver as defined in line.Let's look at the onReceive method of thatbroadcast receiver.First, it checks to see whether it'sreceiving a battery_changed intent.If so, it determines whether the broadcastisnew or cached, by calling is initialsticky broadcast.This method returns true if this intent isa cached value.And after that the code sets the text todisplay.So that's all for this lesson on broadcastreceivers.Please join me next time, when we'll talkabout Threads, AsyncTasks, and Handlers.See you then.[BLANK_AUDIO]