Merge "New Scheduling class." into jb-mr2-docs
This commit is contained in:
committed by
Android (Google) Code Review
commit
a9fcf6620d
BIN
docs/downloads/training/Scheduler.zip
Normal file
BIN
docs/downloads/training/Scheduler.zip
Normal file
Binary file not shown.
8
docs/html/training/best-background.jd
Normal file
8
docs/html/training/best-background.jd
Normal file
@@ -0,0 +1,8 @@
|
||||
page.title=Best Practices for Background Jobs
|
||||
page.trainingcourse=true
|
||||
|
||||
@jd:body
|
||||
|
||||
|
||||
<p>These classes show you how to run jobs in the background to boost your
|
||||
application's performance and minimize its drain on the battery.</p>
|
||||
312
docs/html/training/scheduling/alarms.jd
Normal file
312
docs/html/training/scheduling/alarms.jd
Normal file
@@ -0,0 +1,312 @@
|
||||
page.title=Scheduling Repeating Alarms
|
||||
parent.title=Using Wake Locks
|
||||
parent.link=index.html
|
||||
|
||||
trainingnavtop=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<!-- table of contents -->
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#set">Set a Repeating Alarm</a></li>
|
||||
<li><a href="#cancel">Cancel an Alarm</a></li>
|
||||
<li><a href="#boot">Start an Alarm When the Device Boots</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
|
||||
<div class="download-box">
|
||||
<a href="{@docRoot}shareables/training/Scheduler.zip"
|
||||
class="button">Download the sample</a>
|
||||
<p class="filename">Scheduler.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Alarms (based on the {@link android.app.AlarmManager} class) give you a way to perform
|
||||
time-based operations outside the lifetime of your application.
|
||||
For example, you could use an alarm to initiate a long-running operation, such
|
||||
as starting a service once a day to download a weather forecast.</p>
|
||||
|
||||
<p>Alarms have these characteristics:</p>
|
||||
<ul>
|
||||
|
||||
<li>They let you fire Intents at set times and/or intervals.</li>
|
||||
|
||||
<li>You can use them in conjunction with broadcast receivers to start services and perform
|
||||
other operations.</li>
|
||||
|
||||
<li>They operate outside of your application, so you can use them to trigger events or
|
||||
actions even when your app is not running, and even if the device itself is asleep.</li>
|
||||
|
||||
<li>They help you to minimize your app's resource requirements. You can schedule operations
|
||||
without relying on timers or continuously running background services.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p class="note"><strong>Note:</strong> For timing operations that are guaranteed to occur
|
||||
<em>during</em> the lifetime of your application,
|
||||
instead consider using the {@link android.os.Handler} class in conjunction with
|
||||
{@link java.util.Timer} and {@link java.lang.Thread}. This approach gives Android better
|
||||
control over system resources.</p>
|
||||
|
||||
<h2 id="set">Set a Repeating Alarm</h2>
|
||||
|
||||
<p>As described above, repeating alarms are a good choice for scheduling regular events or
|
||||
data lookups. A repeating alarm has the following characteristics:</p>
|
||||
|
||||
<ul>
|
||||
<li>A alarm type. For more discussion, see <a href="#type">Choose an alarm type</a>.</li>
|
||||
<li>A trigger time. If the trigger time you specify is in the past, the alarm triggers
|
||||
immediately.</li>
|
||||
<li>The alarm's interval. For example, once a day, every hour, every 5 seconds, and so on.</li>
|
||||
<li>A pending intent that fires when the alarm is triggered. When you set a second alarm
|
||||
that uses the same pending intent, it replaces the original alarm.</li>
|
||||
</ul>
|
||||
|
||||
<p>Every choice you make in designing your repeating alarm can have consequences in how your
|
||||
app uses (or abuses) system resources. Even a carefully managed alarm can have a major impact
|
||||
on battery life. Follow these guidelines as you design your app:</p>
|
||||
|
||||
<ul>
|
||||
<li>Keep your alarm frequency to a minimum.</li>
|
||||
<li>Don't wake up the device unnecessarily (this behavior is determined by the alarm type,
|
||||
as described in <a href="#type">Choose an alarm type</a>).</li>
|
||||
<li>Don't make your alarm's trigger time any more precise than it has to be:
|
||||
|
||||
<ul>
|
||||
<li>Use {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()} instead
|
||||
of {@link android.app.AlarmManager#setRepeating setRepeating()} whenever possible.
|
||||
When you use {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()},
|
||||
Android synchronizes multiple inexact repeating alarms and fires
|
||||
them at the same time. This reduces the drain on the battery.</li>
|
||||
<li>If your alarm's behavior is based on an interval (for example, your alarm
|
||||
fires once an hour) rather than a precise trigger time (for example, your alarm fires at
|
||||
7 a.m. sharp and every 20 minutes after that), use an {@code ELAPSED_REALTIME}
|
||||
alarm type.</li>
|
||||
</ul></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3 id="type">Choose an alarm type</h3>
|
||||
|
||||
<p>One of the first considerations in using a repeating alarm is what its type should be.</p>
|
||||
|
||||
|
||||
<p>There are two general clock types for alarms: "elapsed real time" and "real time clock"
|
||||
(RTC).
|
||||
Elapsed real time uses the "time since system boot" as a
|
||||
reference, and real time clock uses UTC (wall clock) time. This means that
|
||||
elapsed real time is suited to setting an alarm based on the passage of time (for
|
||||
example, an alarm that fires every 30 seconds) since it isn't affected by
|
||||
time zone/locale. The real time clock type is better suited for alarms that are dependent
|
||||
on current locale.</p>
|
||||
|
||||
<p>Both types have a "wakeup" version, which says to wake up the device's CPU if the
|
||||
screen is off. This ensures that the alarm will fire at the scheduled time. This is useful
|
||||
if your app has a time dependency—for example, if it has a limited window to perform a
|
||||
particular operation. If you don't use the wakeup version of your alarm type, then
|
||||
all the repeating alarms will fire when your device is next awake.</p>
|
||||
|
||||
<p>If you simply need your alarm to fire at a particular interval (for example, every half
|
||||
hour), use one of the elapsed real time types. In general, this is the better choice.</p>
|
||||
|
||||
<p>If you need your alarm to fire at a particular time of day,
|
||||
then choose one of the clock-based real time clock types. Note, however, that this approach can
|
||||
have some drawbacks—the app may not translate well to other locales, and if the user
|
||||
changes the device's time setting, it could cause unexpected behavior in your app.</p>
|
||||
|
||||
<p>Here is the list of types:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>{@link android.app.AlarmManager#ELAPSED_REALTIME}—Fires the pending intent based
|
||||
on the amount of time since the device was booted, but doesn't wake up the device. The
|
||||
elapsed time includes any time during which the device was asleep.</li>
|
||||
|
||||
<li>{@link android.app.AlarmManager#ELAPSED_REALTIME_WAKEUP}—Wakes up the device and
|
||||
fires the pending intent after the specified length of time has elapsed since device
|
||||
boot.</li>
|
||||
|
||||
<li>{@link android.app.AlarmManager#RTC}—Fires the pending intent
|
||||
at the specified time but does not wake up the device.</li>
|
||||
|
||||
<li>{@link android.app.AlarmManager#RTC_WAKEUP}—Wakes up the
|
||||
device to fire the pending intent at the specified time.</li>
|
||||
</ul>
|
||||
|
||||
<h4>ELAPSED_REALTIME_WAKEUP examples</h3>
|
||||
|
||||
<p>Here are some examples of using {@link android.app.AlarmManager#ELAPSED_REALTIME_WAKEUP}.
|
||||
</p>
|
||||
|
||||
<p>Wake up the device to fire the alarm in 30 minutes, and every 30 minutes
|
||||
after that:</p>
|
||||
|
||||
<pre>
|
||||
// Hopefully your alarm will have a lower frequency than this!
|
||||
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
AlarmManager.INTERVAL_HALF_HOUR,
|
||||
AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);</pre>
|
||||
|
||||
<p>Wake up the device to fire a one-time (non-repeating) alarm in one minute:</p>
|
||||
|
||||
<pre>private AlarmManager alarmMgr;
|
||||
private PendingIntent alarmIntent;
|
||||
...
|
||||
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
|
||||
Intent intent = new Intent(context, AlarmReceiver.class);
|
||||
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
|
||||
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||
SystemClock.elapsedRealtime() +
|
||||
60 * 1000, alarmIntent);</pre>
|
||||
|
||||
|
||||
<h4>RTC examples</h3>
|
||||
|
||||
<p>Here are some examples of using {@link android.app.AlarmManager#RTC_WAKEUP}.</p>
|
||||
|
||||
<p>Wake up the device to fire the alarm at approximately 2:00 p.m., and repeat once a day
|
||||
at the same time:</p>
|
||||
|
||||
<pre>// Set the alarm to start at approximately 2:00 p.m.
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 14);
|
||||
|
||||
// With setInexactRepeating(), you have to use one of the AlarmManager interval
|
||||
// constants--in this case, AlarmManager.INTERVAL_DAY.
|
||||
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
|
||||
AlarmManager.INTERVAL_DAY, alarmIntent);</pre>
|
||||
|
||||
<p>Wake up the device to fire the alarm at precisely 8:30 a.m., and every 20 minutes
|
||||
thereafter:</p>
|
||||
|
||||
<pre>private AlarmManager alarmMgr;
|
||||
private PendingIntent alarmIntent;
|
||||
...
|
||||
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
|
||||
Intent intent = new Intent(context, AlarmReceiver.class);
|
||||
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
||||
|
||||
// Set the alarm to start at 8:30 a.m.
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 8);
|
||||
calendar.set(Calendar.MINUTE, 30);
|
||||
|
||||
// setRepeating() lets you specify a precise custom interval--in this case,
|
||||
// 20 minutes.
|
||||
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
|
||||
1000 * 60 * 20, alarmIntent);</pre>
|
||||
|
||||
<h3>Decide how precise your alarm needs to be</h3>
|
||||
|
||||
<p>As described above, choosing the alarm type is often the first step in creating an alarm.
|
||||
A further distinction is how precise you need your alarm to be. For most apps,
|
||||
{@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()} is the right
|
||||
choice.
|
||||
When you use this method, Android synchronizes multiple inexact repeating alarms and fires
|
||||
them at the same time. This reduces the drain on the battery.</p>
|
||||
|
||||
<p>For the rare app that has rigid time requirements—for example, the alarm needs to
|
||||
fire precisely at 8:30 a.m., and every hour on the hour
|
||||
thereafter—use {@link android.app.AlarmManager#setRepeating setRepeating()}. But you
|
||||
should avoid using exact alarms if possible.</p>
|
||||
|
||||
<p>With {@link android.app.AlarmManager#setInexactRepeating setInexactRepeating()},
|
||||
you can't specify a custom interval the way you can with
|
||||
{@link android.app.AlarmManager#setRepeating setRepeating()}. You have to use one of the
|
||||
interval constants, such as {@link android.app.AlarmManager#INTERVAL_FIFTEEN_MINUTES},
|
||||
{@link android.app.AlarmManager#INTERVAL_DAY}, and so on. See {@link android.app.AlarmManager}
|
||||
for the complete list.
|
||||
</p>
|
||||
|
||||
<h2 id="cancel">Cancel an Alarm</h2>
|
||||
|
||||
<p>Depending on your app, you may want to include the ability to cancel the alarm.
|
||||
To cancel an alarm, call {@link android.app.AlarmManager#cancel cancel()} on the Alarm
|
||||
Manager, passing in the {@link android.app.PendingIntent} you no longer want to fire. For
|
||||
example:</p>
|
||||
|
||||
<pre>// If the alarm has been set, cancel it.
|
||||
if (alarmMgr!= null) {
|
||||
alarmMgr.cancel(alarmIntent);
|
||||
}</pre>
|
||||
|
||||
<h2 id="boot">Start an Alarm When the Device Boots</h2>
|
||||
|
||||
<p>By default, all alarms are canceled when a device shuts down.
|
||||
To prevent this from happening, you can design your application
|
||||
to automatically restart a repeating alarm if the user reboots the device. This ensures
|
||||
that the {@link android.app.AlarmManager} will continue doing its task without the user
|
||||
needing to manually restart the alarm.</p>
|
||||
|
||||
|
||||
<p>Here are the steps:</p>
|
||||
<ol>
|
||||
<li>Set the <a href="{@docRoot}reference/android/Manifest.permission.html#RECEIVE_BOOT_COMPLETED">
|
||||
{@code RECEIVE_BOOT_COMPLETED}</a> permission in your application's manifest. This allows
|
||||
your app to receive the
|
||||
{@link android.content.Intent#ACTION_BOOT_COMPLETED} that is broadcast after the system
|
||||
finishes booting (this only works if the app has already been launched by the user at least once):
|
||||
<pre>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/></pre>
|
||||
</li>
|
||||
|
||||
<li>Implement a {@link android.content.BroadcastReceiver} to receive the broadcast:
|
||||
<pre>public class SampleBootReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
|
||||
// Set the alarm here.
|
||||
}
|
||||
}
|
||||
}</pre></li>
|
||||
|
||||
<li>Add the receiver to your app's manifest file with an intent filter that filters on
|
||||
the {@link android.content.Intent#ACTION_BOOT_COMPLETED} action:
|
||||
|
||||
<pre><receiver android:name=".SampleBootReceiver"
|
||||
android:enabled="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
|
||||
</intent-filter>
|
||||
</receiver></pre>
|
||||
|
||||
|
||||
<p>Notice that in the manifest, the boot receiver is set to
|
||||
{@code android:enabled="false"}. This means that the receiver will not be called
|
||||
unless the application explicitly enables it. This prevents the boot receiver from being
|
||||
called unnecessarily. You can enable a receiver (for example, if the user sets an alarm)
|
||||
as follows:</p>
|
||||
|
||||
<pre>ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
pm.setComponentEnabledSetting(receiver,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||
PackageManager.DONT_KILL_APP);
|
||||
</pre>
|
||||
|
||||
<p>Once you enable the receiver this way, it will stay enabled, even if the user reboots
|
||||
the device. In other words, programmatically enabling the receiver overrides the
|
||||
manifest setting, even across reboots. The receiver will stay enabled until your app disables it.
|
||||
You can disable a receiver (for example, if the user cancels an alarm) as follows:</p>
|
||||
|
||||
<pre>ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
pm.setComponentEnabledSetting(receiver,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
PackageManager.DONT_KILL_APP);</pre>
|
||||
|
||||
</li>
|
||||
</ol>
|
||||
66
docs/html/training/scheduling/index.jd
Normal file
66
docs/html/training/scheduling/index.jd
Normal file
@@ -0,0 +1,66 @@
|
||||
page.title=Managing Device Awake State
|
||||
page.tags=""
|
||||
|
||||
trainingnavtop=true
|
||||
startpage=true
|
||||
|
||||
|
||||
@jd:body
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
|
||||
<h2>Dependencies and prerequisites</h2>
|
||||
|
||||
<ul>
|
||||
<li>Android 1.6 (API Level 4) or higher</li>
|
||||
</ul>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
|
||||
<div class="download-box">
|
||||
<a href="{@docRoot}shareables/training/Scheduler.zip"
|
||||
class="button">Download the sample</a>
|
||||
<p class="filename">Scheduler.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
When an Android device is left idle, it will first dim, then turn off the screen, and
|
||||
ultimately turn off the CPU. This prevents the device's battery from quickly getting
|
||||
drained. Yet there are times when your application might require a different behavior:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Apps such as games or movie apps may need to keep the screen turned on.</p>
|
||||
|
||||
<li>Other applications may not need the screen to remain on, but they may require the CPU
|
||||
to keep running until a critical operation finishes.</p>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This class describes how to keep a device awake when necessary without draining
|
||||
its battery.
|
||||
</p>
|
||||
<h2>Lessons</h2>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<strong><a href="wakelock.html">Keeping the Device Awake</a></strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Learn how to keep the screen or CPU awake as needed, while minimizing the impact
|
||||
on battery life.
|
||||
</dd>
|
||||
<dt>
|
||||
<strong><a href="alarms.html">Scheduling Repeating Alarms</a></strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Learn how to use repeating alarms to schedule operations that take place outside
|
||||
of the lifetime of the application, even if the application is not running and/or the
|
||||
device is asleep.
|
||||
</dd>
|
||||
</dl>
|
||||
215
docs/html/training/scheduling/wakelock.jd
Normal file
215
docs/html/training/scheduling/wakelock.jd
Normal file
@@ -0,0 +1,215 @@
|
||||
page.title=Keeping the Device Awake
|
||||
|
||||
trainingnavtop=true
|
||||
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<!-- table of contents -->
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#screen">Keep the Screen On</a></li>
|
||||
<li><a href="#cpu">Keep the CPU On</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>Try it out</h2>
|
||||
|
||||
<div class="download-box">
|
||||
<a href="{@docRoot}shareables/training/Scheduler.zip"
|
||||
class="button">Download the sample</a>
|
||||
<p class="filename">Scheduler.zip</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p>To avoid draining the battery, an Android device that is left idle quickly falls asleep.
|
||||
However, there are times when an application needs to wake up the screen or the CPU
|
||||
and keep it awake to complete some work.</p>
|
||||
|
||||
<p>The approach you take depends on the needs of your app. However, a general rule of thumb
|
||||
is that you should use the most lightweight approach possible for your app, to minimize your
|
||||
app's impact on system resources. The following sections describe how to handle the cases
|
||||
where the device's default sleep behavior is incompatible with the requirements of your app.</p>
|
||||
|
||||
<h2 id="screen">Keep the Screen On</h2>
|
||||
|
||||
<p>Certain apps need to keep the screen turned on, such as games or movie apps. The best
|
||||
way to do this is to use the
|
||||
{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}
|
||||
in your activity (and only in an activity, never in a service or
|
||||
other app component). For example:</p>
|
||||
|
||||
<pre>public class MainActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
<strong>getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);</strong>
|
||||
}</pre>
|
||||
|
||||
<p>The advantage of this approach is that unlike wake locks (discussed in <a href="#cpu">
|
||||
Keep the CPU On</a>), it doesn't require special permission, and the platform correctly
|
||||
manages the user moving between applications, without your app needing to worry about
|
||||
releasing unused resources.</p>
|
||||
|
||||
<p>Another way to implement this is in your application's layout XML file, by using the
|
||||
{@link android.R.attr#keepScreenOn android:keepScreenOn} attribute:</p>
|
||||
|
||||
<pre><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
<strong>android:keepScreenOn="true"></strong>
|
||||
...
|
||||
</RelativeLayout></pre>
|
||||
|
||||
<p>Using <code>android:keepScreenOn="true"</code> is equivalent to using
|
||||
{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}.
|
||||
You can use whichever approach is best for your app. The advantage of setting the flag
|
||||
programmatically in your activity is that it gives you the option of programmatically
|
||||
clearing the flag later and thereby allowing the screen to turn off.</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong> You don't need to clear the
|
||||
{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}
|
||||
flag unless you no longer want the screen to
|
||||
stay on in your running application (for example, if you want the screen to time out
|
||||
after a certain period of inactivity). The window manager takes care of
|
||||
ensuring that the right things happen when the app goes into the background or returns to
|
||||
the foreground. But if you want to explicitly clear the flag and thereby allow the screen to
|
||||
turn off again, use {@link android.view.Window#clearFlags clearFlags()}:
|
||||
{@code getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)}.</p>
|
||||
|
||||
<h2 id="cpu">Keep the CPU On</h2>
|
||||
|
||||
<div class="sidebox-wrapper">
|
||||
<div class="sidebox">
|
||||
<h2>Alternatives to using wake locks</h2>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>If your app is performing long-running HTTP downloads, consider using
|
||||
{@link android.app.DownloadManager}.</li>
|
||||
|
||||
<li>If your app is synchronizing data from an external server, consider creating a
|
||||
<a href="{@docRoot}training/sync-adapters/index.html">sync
|
||||
adapter</a>.</li>
|
||||
|
||||
<li>If your app relies on background services, consider using
|
||||
<a href="{@docRoot}training/scheduling/alarms.html">repeating alarms</a>
|
||||
or <a href="{@docRoot}google/gcm/index.html">Google Cloud Messaging</a> to trigger these
|
||||
services at specific intervals.</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p>If you need to keep the CPU running in order to complete some work before the device goes
|
||||
to sleep, you can use a {@link android.os.PowerManager} system service feature called
|
||||
wake locks. Wake locks allow your application to control the power state of the host device.</p>
|
||||
|
||||
<p>Creating and holding wake locks can have a dramatic impact on the host device's battery
|
||||
life. Thus you should use wake locks only when strictly necessary
|
||||
and hold them for as short a time as possible. For example, you should never need to use a
|
||||
wake lock in an activity. As described above, if you want
|
||||
to keep the screen on in your activity, use
|
||||
{@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON FLAG_KEEP_SCREEN_ON}.</p>
|
||||
|
||||
|
||||
<p>One legitimate case for using a wake lock might be a background service
|
||||
that needs to grab a wake lock to keep the CPU running to do work while the screen is off.
|
||||
Again, though, this practice should be minimized because of its impact on battery life.</p>
|
||||
|
||||
<p>To use a wake lock, the first step is to add the {@link android.Manifest.permission#WAKE_LOCK}
|
||||
permission to your application's manifest file:</p>
|
||||
|
||||
<pre><uses-permission android:name="android.permission.WAKE_LOCK" /></pre>
|
||||
|
||||
<p>If your app includes a broadcast receiver that uses a service to do some
|
||||
work, you can manage your wake lock through a
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver}, as described in
|
||||
<a href="#wakeful">Using a WakefulBroadcastReceiver</a>. This is the preferred approach.
|
||||
If your app doesn't follow that pattern, here is how you set a wake lock
|
||||
directly:</p>
|
||||
|
||||
<pre>
|
||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||
Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
"MyWakelockTag");
|
||||
wakeLock.acquire();</pre>
|
||||
|
||||
<p>To release the wake lock, call
|
||||
{@link android.os.PowerManager.WakeLock#release wakelock.release()}. This releases your
|
||||
claim to the CPU. It's important to release a wake lock as soon as your app is finished
|
||||
using it to avoid draining the battery.</p>
|
||||
|
||||
<h3 id="wakeful">Using WakefulBroadcastReceiver</h3>
|
||||
|
||||
<p>Using a broadcast receiver in conjunction with a service lets you manage the life cycle
|
||||
of a background task.</p>
|
||||
|
||||
<p>A {@link android.support.v4.content.WakefulBroadcastReceiver} is a special type of
|
||||
broadcast receiver that takes care of
|
||||
creating and managing a
|
||||
{@link android.os.PowerManager#PARTIAL_WAKE_LOCK} for your app. A
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver}
|
||||
passes off the work to a {@link android.app.Service}
|
||||
(typically an
|
||||
{@link android.app.IntentService}), while ensuring that the device does not
|
||||
go back to sleep in the transition. If you don't hold a wake lock while transitioning
|
||||
the work to a service, you are effectively allowing the device to go back to sleep before
|
||||
the work completes. The net result is that the app might not finish doing the work until
|
||||
some arbitrary point in the future, which is not what you want.</p>
|
||||
|
||||
<p>The first step in using a
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver} is to add it to your
|
||||
manifest, as with any other broadcast receiver:</p>
|
||||
|
||||
<pre><receiver android:name=".MyWakefulReceiver"></receiver></pre>
|
||||
|
||||
<p>The following code starts {@code MyIntentService} with the method
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}.
|
||||
This method is comparable to {@link android.content.Context#startService startService()}, except that
|
||||
the {@link android.support.v4.content.WakefulBroadcastReceiver} is holding a
|
||||
wake lock when the service starts. The intent that is passed with
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver#startWakefulService startWakefulService()}
|
||||
holds an extra identifying the wake lock:</p>
|
||||
|
||||
<pre>public class MyWakefulReceiver extends WakefulBroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
// Start the service, keeping the device awake while the service is
|
||||
// launching. This is the Intent to deliver to the service.
|
||||
Intent service = new Intent(context, MyIntentService.class);
|
||||
startWakefulService(context, service);
|
||||
}
|
||||
}</pre>
|
||||
|
||||
<p>When the service is finished, it calls
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent MyWakefulReceiver.completeWakefulIntent()}
|
||||
to release the wake lock. The
|
||||
{@link android.support.v4.content.WakefulBroadcastReceiver#completeWakefulIntent completeWakefulIntent()}
|
||||
method has as its parameter the same intent that was
|
||||
passed in from the {@link android.support.v4.content.WakefulBroadcastReceiver}:</p>
|
||||
<pre>
|
||||
public class MyIntentService extends IntentService {
|
||||
public static final int NOTIFICATION_ID = 1;
|
||||
private NotificationManager mNotificationManager;
|
||||
NotificationCompat.Builder builder;
|
||||
public MyIntentService() {
|
||||
super("MyIntentService");
|
||||
}
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
Bundle extras = intent.getExtras();
|
||||
// Do the work that requires your app to keep the CPU running.
|
||||
// ...
|
||||
// Release the wake lock provided by the WakefulBroadcastReceiver.
|
||||
MyWakefulReceiver.completeWakefulIntent(intent);
|
||||
}
|
||||
}</pre>
|
||||
@@ -991,6 +991,75 @@ include the action bar on devices running Android 2.1 or higher."
|
||||
</ul>
|
||||
</li> <!-- end of User Input -->
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/best-background.html">
|
||||
<span class="small">Best Practices for</span><br/>
|
||||
Background Jobs
|
||||
</a>
|
||||
</div>
|
||||
<ul>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/run-background-service/index.html"
|
||||
description=
|
||||
"How to improve UI performance and responsiveness by sending work to a
|
||||
Service running in the background"
|
||||
>Running in a Background Service</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/create-service.html">
|
||||
Creating a Background Service
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/send-request.html">
|
||||
Sending Work Requests to the Background Service
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/report-status.html">
|
||||
Reporting Work Status
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/load-data-background/index.html"
|
||||
description="How to use CursorLoader to query data without
|
||||
affecting UI responsiveness."
|
||||
>Loading Data in the Background</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/load-data-background/setup-loader.html">
|
||||
Running a Query with a CursorLoader</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/load-data-background/handle-results.html">
|
||||
Handling the Results</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/scheduling/index.html"
|
||||
description="How to use repeating alarms and wake locks
|
||||
to run background jobs."
|
||||
>Managing Device Awake State</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/scheduling/wakelock.html">
|
||||
Keeping the Device Awake</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/scheduling/alarms.html">
|
||||
Scheduling Repeating Alarms</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li> <!-- end of Background Jobs -->
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/best-performance.html">
|
||||
@@ -1036,47 +1105,6 @@ include the action bar on devices running Android 2.1 or higher."
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/run-background-service/index.html"
|
||||
description=
|
||||
"How to improve UI performance and responsiveness by sending work to a
|
||||
Service running in the background"
|
||||
>Running in a Background Service</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/create-service.html">
|
||||
Creating a Background Service
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/send-request.html">
|
||||
Sending Work Requests to the Background Service
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/run-background-service/report-status.html">
|
||||
Reporting Work Status
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/load-data-background/index.html"
|
||||
description="How to use CursorLoader to query data without
|
||||
affecting UI responsiveness."
|
||||
>Loading Data in the Background</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/load-data-background/setup-loader.html">
|
||||
Running a Query with a CursorLoader</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/load-data-background/handle-results.html">
|
||||
Handling the Results</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="/training/monitoring-device-state/index.html"
|
||||
|
||||
Reference in New Issue
Block a user