Thứ Tư, 17 tháng 10, 2012
android - Working in the Background
Working in the Background
WHAT’S IN THIS CHAPTER?
➤ Creating, starting, and stopping Services
➤ Binding Services to Activities
➤ Setting Service priority to foreground
➤ Using AsyncTasks to manage background processing
➤ Creating background threads and using Handlers to synchronize with
the GUI thread
➤ Displaying Toasts
➤ Using the Notification Manager to notify users of application events
➤ Creating insistent and ongoing Notifications
➤ Using Alarms to schedule application events
Android offers the Serviceclass to create application components specifically to handle opera-
tions and functionality that should run invisibly, without a user interface.
Android accords Services a higher priority than inactive Activities, so they’re less likely to be
killed when the system requires resources. In fact, should the run time prematurely terminate a
Service that’s been started, it can be configured to restart as soon as sufficient resources become
available. In extreme cases, the termination of a Service — such as an interruption in music
playback — will noticeably affect the user experience, and in these cases a Service’s priority can
be raised to the equivalent of a foreground Activity.
By using Services, you can ensure that your applications continue to run and respond to events,
even when they’re not in active use.
Services run without a dedicated GUI, but, like Act ivities and Broadcast Receivers, they still exe-
cute in the main thread of the application’s process. To help keep your applications responsive,
you’ll learn to move time-consuming processes (like network lookups) into background threads using
the Thread and AsyncTask classes.
Android offers several techniques for applications to communicate with users without an Activity.
You’ll learn how to use Notifications and Toasts to alert and update users without interrupting the
active application.
Toasts are a transient, non-modal dialog-box mechanis m used to display information to users with-
out stealing focus from the active application. You’ll learn to display Toasts from any application
component to send unobtrusive on-screen messages to your users.
Where Toasts are silent and transient,Notifications represent a more robust mechanism for alerting
users. In many cases, when the user isn’t actively using the mobile phone it sits silent and unwatched in
a pocket or on a desk until it rings, vibrates, or flashes. Should a user miss these alerts, status bar icons
are used to indicate that an event has occurred. All these attention-grabbing antics are available to your
Android application through Notifications.
Alarms provide a mechanism for firing Intents at set times, outside the control of your application life
cycle. You’ll learn to use Alarms to start Services, open Activities, or broadcast Intents based on either
the clock time or the time elapsed since device boot. An Alarm will fire even after its owner application
has been closed, and can (if required) wake a device from sleep.
NTRODUCING SERVICES
Unlike Activities, which present a rich graphical interface to users, Services run in the background —
updating your Content Providers, firing Intents, and triggering Notifications. They are the perfect
means of performing ongoing or regular processing and of handling events even when your applica-
tion’s Activities are invisible or inactive, or have been closed.
Services are started, stopped, and controlled from other application components, including other
Services, Activities, and Broadcast Receivers. If your application performs actions that don’t depend
directly on user input, Services may be the answer.
Started Services always have higher priority than inactive or invisible Activities, making them less likely
to be terminated by the run time’s resource management. The only reason Android will stop a Service
prematurely is to provide additional resources for a foreground component (usually an Activity). When
that happens, your Service will be restarted automatically when resources become available.
If your Service is interacting directly with the user (for example, by playing music) it may be necessary to
increase its priority to that of a foreground Activity. This will ensure that your Service isn’t terminated
except in extreme circumstances, but reduces the run time’s ability to manage its resources, potentially
degrading the overall user experience.
Applications that update regularly but only rarely or intermittently need user interaction are good
candidates for implementation as Services. MP3 pl ayers and sports-score monitors are examples of
applications that should continue to run and update without a visible Activity.
Further examples can be found within the software stack itself: Android implements several Services,
including the Location Manager, Media Controller, and Notification Manager.
Creating and Controlling Services
In the following sections you’ll learn how to create a new Service, and how to start and stop it using
Intents and the startServicemethod. Later you’ll learn how to bind a Service to an Activity to provide
a richer communications interface.
Creating a Service
To define a Service, create a new class that extendsService. You’ll need to overrideonBind and
onCreate , as shown in Listing 9-1.
>>>>> source
In most cases you’ll also want to overrideonStartCommand. This is called whenever the Service is started
with a call to startService, so it may be executed several times within a Service’s lifetime. You should
ensure that your Service accounts for this.
The onStartCommand handler replaces the onStartevent that was used prior to Android 2.0. By con-
trast, it enables you to tell the system how to handle restarts if the Service is killed by the system prior
to an explicit call to stopService or stopSelf .
The following snippet extends Listing 9-1 to show the skeleton code for overriding the onStartCommand
handler. Note that it returns a value that controls howthe system will respond if the Service is restarted
after being killed by the run time.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Launch a background thread to do processing.
return Service.START_STICKY;
}
Services are launched on the main Application thread, meaning that any processing done in the
onStartCommand handler will happen on the main GUI thread. The standard pattern for implementing
a Service is to create and run a new thread fromonStartCommand to perform the processing in the
background and stop the Service when it’s complete (you will be shown how to create and manage
background threads later in this chapter).
This pattern lets onStartCommand complete quickly, and lets you control the restart behavior using one
of the following Serviceconstants:
➤ START_STICKY Describes the standard behavior, which is similar to the way in which
onStartwas implemented prior to Android 2.0. If you return this value,onStartCommand will
be called any time your Service restarts after being terminated by the run time. Note that on a
restart the Intent parameter passed in toonStartCommand will be null.
This mode is typically used for Services that handle their own states, and that are explicitly
started and stopped as required (via startServiceand stopService ). This includes Services
that play music or handle other ongoing background tasks.
➤ START_NOT_STICKY This mode is used for Services that are started to process specific actions
or commands. Typically they will usestopSelf to terminate once that command has been
completed.
Following termination by the run time, Services set to this mode will restart only if there are
pending start calls. If nostartServicecalls have been made since the Service was terminated,
the Service will be stopped without a call being made to onStartCommand.
This mode is ideal for Services that handle specific requests, particularly regular processing
such as updates or network polling. Rather than restarting the Service during a period of
resource contention, it’s often more prudent tolet the Service stop and retry at the next sched-
uled interval.
➤ START_REDELIVER_INTENT In some circumstances you will want to ensure that the com-
mands you have requested from your Service are completed.
This mode is a combination of the first two — if the Service is terminated by the run time, it
will restart only if there are pending start calls or the process was killed prior to its calling
stopSelf .
In the latter case, a call toonStartCommand will be made, passing in the initial Intent whose
processing did not properly complete.
Note that each mode requires you to explicitly stop your Service, through stopService or stopSelf
respectively, when your processing has completed . Both of these methods are discussed in more detail
later in this chapter.
Prior to Android SDK 2.0 (SDK API level 5) the Service class triggered theonStart
event handler to let you perform actions when the Service started. Implementing
the onStarthandler is now the equivalent of overriding onStartCommand and
returning the START_STICKYflag.
The restart mode you specify in youronStartCommand return value will affect the parameter values
passed in to subsequent calls.
Initially the Intent will be the parameter you passed in to startServiceto start your Service. After
system-based restarts it will be either null, in the case ofSTART_STICKYmode, or the original Intent, if
the mode is set to START_REDELIVER_INTENT.
The flag parameter can be used to discover how the Service was started. In particular you can use the
code snippet shown in Listing 9-2 to determine if either of the following cases is true:
➤ START_FLAG_REDELIVERY Indicates that the Intent parameter is a redelivery caused by the
system run time’s having terminated the Service before it was explicitly stopped by a call to
stopSelf .
➤ START_FLAG_RETRY Indicates that the Service has been restarted after an abnormal termina-
tion. Passed in when the Service was previously set to START_STICKY.
>> source
Registering a Service in the Manifest
Once you’ve constructed a new Service, you have to register it in the application manifest.
Do this by including a <service> tag within the application node. Use the requires-permission
attribute to require a uses-permission for other applications to access this Service.
The following is the servicetag you’d add for the skeleton Service you created earlier:
<service android:enabled="true" android:name=".MyService"/>
Self-Terminating a Service
Once your Service has completed the actions or processing it was started for, you should make a call
to stopSelf , either without a parameter to force a stop, or by passing in a startIdvalue to insure pro-
cessing has been completed for each instance of startServicecalled so far, as shown in the following
snippet:
stopSelf(startId);
By explicitly stopping the Service when your processing is complete, you allow the system to recover
the resources otherwise required to keep it running. Due to the high priority of Services they are not
commonly killed by the run time, so self-termination c an significantly improve the resource footprint
of your application.
Starting, Controlling, and Interacting with a Service
To start a Service, call startService; you can either use an action to implicitly start a Service with the
appropriate Intent Receiver registered, or you can explicitly specify the Service using its class. If the
Service requires permissions that your application does not have, the call to startServicewill throw a
SecurityException.
In both cases you can pass values in to the Service’s onStarthandler by adding extras to the Intent, as
shown in Listing 9-3, which demonstrates bot h techniques available for starting a Service.
An Earthquake Monitoring Service Example
In this chapter you’ll modify the Earthquake example you started in Chapter 5 (and continued to
enhance in Chapters 6, 7, and 8). In this example you’ll move the earthquake updating and processing
functionality into a separate Service component.
>>>>>>>>>>>>code
2. Add this new Service to the manifest by adding a new servicetag within the application
node.
<service android:enabled="true" android:name=".EarthquakeService"/>
3. Move therefreshEarthquakes and addNewQuake methods out of theEarthquakeActivity
and into theEarthquakeService.
You’ll need to remove the calls toaddQuakeToArrayand loadQuakesFromProvider(leave
both of these methods in the Earthquake Activity because they’re still required). In the
EarthquakeServicealso remove all references to the earthquakes ArrayList.
>>>code
Đăng ký:
Đăng Nhận xét (Atom)
Không có nhận xét nào:
Đăng nhận xét