0 évaluation0% ont trouvé ce document utile (0 vote)
7 vues7 pages
After an intent is broadcast it will eventually be delivered to the appropriate broadcast receiver. Broadcasting an intent, especially if it goes to multiple applications, can be a relatively expensive operation. Broadcast receivers can't start up operations that will need to call back to the receiver asynchronously.
After an intent is broadcast it will eventually be delivered to the appropriate broadcast receiver. Broadcasting an intent, especially if it goes to multiple applications, can be a relatively expensive operation. Broadcast receivers can't start up operations that will need to call back to the receiver asynchronously.
After an intent is broadcast it will eventually be delivered to the appropriate broadcast receiver. Broadcasting an intent, especially if it goes to multiple applications, can be a relatively expensive operation. Broadcast receivers can't start up operations that will need to call back to the receiver asynchronously.
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 OnReceive is running. In fact, once onReceive returns, Android will sometimes terminate the underlying broadcast receiver. In particular, this, this means that broadcast receivers can't start up operations that will need to call back to the receiver asynchronously at a later time. And of course, that makes sense because there's no guarantee that the broadcast receiver will even exist when that call back occurs. Now examples of these asynchronous callbacks include things like starting a dialogue, or starting an activity via the start activity or result method. So, let's look at some more examples of applications that use broadcast receivers. Here, I'll start up the compound broadcast application. It has a button labeled Broadcast Intent, which when pressed will use the send broadcast method to broadcast a show toast intent. This time, however, there are three broadcast receivers that will receive this intent. So now I'll press the button. And below you see a toast message from receiver one, a second one from receiver two, and the third one from receiver three. Because the compound broadcast application used send to broadcast, the broadcasts were sent out normally and that means that the arrival and processing order were undefined. In this case, the broadcast happened to be handled in one particular order. In other cases or on a different device or if Android changes in the future, that order might be different. So if you really want the broadcast receivers to receive broadcast in a particular order, or if you want each broadcast receiver to have exclusive access to the intent while it's being processed, then you'll want to broadca, you'll want the broadcast to be ordered. And to, you'll do that by using a send ordered broadcast method. And you can do that using some of the methods, some of the following methods from the context class. The first sends an intent to broadcast receivers that have a specified permission in priority order. The second does the same thing, but provide additional parameters for greater control. Let's look at some applications that use these methods to send ordered broadcasts. Here, I'll start up the compound ordered broadcast application. This application displays a button, labeled Broadcast Intent. And when you press the button a show toast intent is broadcast. For this application there are three registered broadcast receivers, of type receiver one, receiver two and receiver three. And each of these has a different priority for receiving the broadcast. Receiver two has the highest priority, receiver one the next highest, and receiver three has the lowest priority. So we expect the receivers to get the broadcast in that order. Receiver two, receiver one, receiver three. However, I put in some code, I put some code in receiver one that aborts the broadcast. So in this case only receiver two and then receiver one should receive the broadcast. So let's see that in action. Now, I'll press the broadcast intent button and you can see a toast message saying that the intent was received by receiver two, and then another saying it was received by receiver one. And apparently, poor receiver three gets left out in the cold. Let's look at the source code for this application. Now here I've got the application open in the IDE. And I'll start by opening up the Android manifest.XML file. And as you can see I statically registered receiver two with a priority of ten. And receiver three I've registered with a priority of one. Now back in the main activity, the code creates an instance of Receiver1, then creates an intentFilter for the show toast intent and then sets the priority to three. So any Receiver2 instance has priority ten. This Receiver1 instance has priority three, and any receiver three instance has priority one. Now, when the broadcast intent button is pressed, the listener calls send ordered broadcast, passing in a new show toast intent. This intent is first received by a receiver two instance, and then by a receiver one instance that was created in this file. Let's open the receiver one code. Now here in on receive you see that the code checks to see whether this is an ordered broadcast. And if so, it calls abort broadcast, which consumes the broadcast, and in this case, prevents it from being sent on to receiver three. Now let's also look at a slightly more complicated use of ordered broadcast. In this application, called Ordered Broadcast with Result Receiver, we'll see that a single toast message is displayed, that shows all the broadcast receivers that receive this intent and that indicates the order in which they received it. Now here, I'll start the application. Now I'll press it's Broadcast Intent button and there's the toast message. It shows that receiver two received the intent, then receiver one, then receiver three. Let's look at the source code. Now here's the application open in the IDE. Now, I'll open the main activity and go to the listener for the broadcast intent button. As you can see, this code uses the second form of the send broadcast method. One of the interesting parameters of this method is a broadcast receiver, I'll call it the result receiver that will receive the intent after all the other broadcast receivers have gotten their chance to receive it. This is useful if the initial broadcast receivers compute some result. Because that result will then be available to this last receiver, and it can get that result by calling get result data, as we see here. Now let's take a look at one of the broadcast receiver classes to see how they compute the result that this result receiver finally displays in the toast message. Now, here's the receiver one class. And as you can see, it's on receive method, calls get result data, to get the current result data. And then it tacks on its own string at the end. And then saves the new string by calling set result data, now since all the broadcast receivers do this in turn, the final result data is a single string showing which receivers received the intent, and the order in which they received it. The last kind of broadcasts I'll talk about today are sticky broadcasts. As I said earlier, non-sticky broadcasts indicate that something's happened at the specific moment in time. They announce events. So once the event is over, it's over. Android disposes of the event and moves on. If a broadcast receiver wasn't registered to receive an intent when it happened, say yesterday, then it shouldn't be told about it now. Because, for example, it might think that the event just happened. And that could lead to all kinds of timing problems and other difficulties. Other events however, indicate state changes that may persist over time. Broadcast receivers that want to know about the current device state, for example, will still want that information even if they weren't registered to be notified when that particular state changed. For example, if the battery level goes very low Android will broadcast this fact to the system. Good applications will want to be good device citizen and not do battery consuming operations when the device is in this low state. So in this case, if a new application starts up and registers to hear about the battery state, that application needs to know right now if the device is in the low battery state. And because of this, Android broadcasts that battery low intent as a sticky broadcast, so sticky intents are cached by Android, and sticky broadcasts of a given intent overwrite any cached values from previous sticky broadcasts of a matching intent. When a broadcast receiver is dynamically registered, any cached intents that match its intent filter will be broadcast to it. In addition, one matching cached intent will be returned to the caller of registered receiver. Now similar to what we saw with non-sticky broadcasts, sticky broadcasts can be sent normally, that is without a defined order, or sequentially, in priority order. Normal sticky broadcasts can use this method. And ordered sticky broadcasts can use this method. And finally, applications that want to broadcast sticky intents must have the broadcast_sticky permission. Let's look at an example application that uses sticky broadcasts. Now here, I'll run the sticky intent application in the emulator. I've also opened a terminal window, and started a Telnet session with that emulator. Now, I'll start the application, which displays the current battery level, and displays the string, reading may be stale. And this last string just indicates that the battery level reading comes from a cached, sticky broadcast, not from a fresh broadcast. If I now go to the terminal window and change the battery level, a new intent will be broadcast reflecting the updated battery level. So now I'll type power capacity 95 and hit return. As you can see the display has been updated. And that display text has changed to indicate that broadcast receiver can distinguish between fresh broadcasts and a cached one. Let's look at the source code for this application. Now here I'm in the IDE. And now I'll open the main activity for this application. It calls register receiver and passes in a broadcast receiver as defined in line. Let's look at the onReceive method of that broadcast receiver. First, it checks to see whether it's receiving a battery_changed intent. If so, it determines whether the broadcast is new or cached, by calling is initial sticky broadcast. This method returns true if this intent is a cached value. And after that the code sets the text to display. So that's all for this lesson on broadcast receivers. Please join me next time, when we'll talk about Threads, AsyncTasks, and Handlers. See you then. [BLANK_AUDIO]