Vous êtes sur la page 1sur 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
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]

Vous aimerez peut-être aussi