Best Practices for Background Jobs
1 Background Operations
- Perform tasks at bg
- Case: a photo-ablum app optimizes its storage by compressing its photos beyond user interactivity.
1.1 Scheduled Jobs
- Scheduled Jobs
- Specify many circumstances
- For example, refresh cached data, specify job to run when sufficient power (no low battery) and an unmetered network (no waste data allotment). Start the job at the appropriate time.
1.2 Services
- Fg service is noticeable by the user.
- Bg service is not noticed by the user but do something silently and for a brief duration.
1.3 Broadcasts
- It’s dangerous that serveral apps respond to the same broadcast.(API26+ reason)
- Register explicit or implicit broadcasts.
1.4 Alarms
AlarmManager
to start apps at a specific time.- Perform an operation at a specified interval, or under particular conditions to use a scheduled job.
2 Running in a Background Service
- UI performance and responsiveness by sending work to a service.
- UI Thread operations.
- Off-load operations onto a separate thread that runs in the bg. IntentService
2.1 Creating a Background Service
- Create an
IntentService
. - The
IntentService
provides a structure for (long-)running an operation on other bg thread. IntentService
isn’t affected by most UI lifecycle events, so it continues to run in circumstances that would shut down anAsyncTask
.- A few limitations:
- It can’t interact directly with UI. Send the results to an
Activity
. - Work requests run sequentially (one by one).
- Can’t be interrupted.
- It can’t interact directly with UI. Send the results to an
- Overide
onHandleIntent()
, and defineIntentService
in manifest file.
2.2.1 Create an IntentService
- Create an named
RSSPullService
class that extendsIntentService
. - Overide
onHandleIntent()
and handle data.
2.2.2 Define the IntentService in the Manifest
<service android:name=".RSSPullService" android:exported="false" />
<service>
doesn’t contain an intent filter. 只能有唯一组件访问这个Service。
2.2 Sending Work Requests to the Background Service
- Send work requests to an
IntentService
.
2.2.1 Create and Send a Work Request to an IntentService
-
Create an explicit
Intent
intent = new Intent(getActivity(), RSSPullService.class); intent.setData(Uri.parse(dataUrl));
2 Call getActivity.startService(intent)
;
2.3 Reporting Work Status
- Use an
Intent
and aLocalBrocastManager
to communicate a work request status to theActivity
that sent the request. - The status of a work request.
2.3.1 Report Status From an IntentService
- Create an
Intent
that contains the status in ites extended data(action or URI). -
Send the
Intent
by callingLocalBroadcastManager.sendBroadcast()
.public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"; // Defines the key for the status "extra" in an Intent public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"; Intent localIntent = new Intent(BROADCAST_ACTION); localIntent.putExtra(EXTENDED_DATA_STATUS, status); LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
2.3.2 Receive Status Broadcasts from an IntentService
- Create
DownloadStateReceiver
class that extends BroadcastReceiver. - Implement the
onReceive
method to handle intents. -
Define the
BroadcastReceiver
and define filters for it match specific actions, categories and data.//Activity or Fragment IntentFilter statusIntentFilter = new IntentFilter(BROADCAST_ACTION); statusIntentFilter.addDataScheme("http");
-
Register
BroadcastReceiver
andIntentFilter
with the system.//Activity or Fragment DownloadStateReceiver receiver = new DownloadStateReceiver(); LocalBroadcastManager.getInstance(this).registerReceiver(receiver, statusIntentFilter);
- A single
BroadcastReceiver
handles many types of broadcastIntent
object with action. - Use a
Notification
to notify the user event happened in the bg while app was not visible.
3 Managing Device Awake State
- Repeat alarms and wake locks to run bg.
- Apps such as games or movie apps need keep the screen turned on.
- Apps need not the screen on but require the CPU to keep running until a critical operations finishes.
3.1 Keeping the Device Awake
- Keep the screen or CPU awake as needed, while minimizing the impact on battery life.
- Avoid draining the battery, an Android device that is left idle quickly falls asleep.
- Use the most lightweight approach possible to handle the cases.
3.1.1 Keep the Screen On
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
in an activity(only an activity, never in a service or other app compontent). Switch the screen to turn off.- The advantage of the approach is that no require special permission, and the platform, no release unused res, unlike wake loacks.
- Other way:
android:keepScreenOn="true"
ClearFlags();
3.1.2 Keep the CPU On
- PowerManager system service feature called wake locks.
- Creating and holding wake locks can have a dramatic impact on device’s battery life.
- A bg service grabs a wake lock to keep the CPU running to do work while the screen is off.
<uses-permission android:name="android.permission.WAKE_LOCK" />
-
WakefullBroadcastReceiver or other way :
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag"); wakeLock.acquire(); //release wakeLock.release();
- Using WakefulBroadcastReceiver
- Use the receiver in conjunction with a service that manages the life cycle of a bg task.
- A special type of
PARTIAL_WAKE_LOCK
- Create
MyWakefullReceiver
that extendsWakefulBroadcastReceiver
, andstartWakefulService()
. MyIntentService
extendsIntentService
, callMyWakefulReceiver.completeWakefulIntent()
to release the wake lock.<receiver android:name=".MyWakefulReceiver" />
3.2 Scheduling Repeating Alarms
- Repeat alarms to schedule operations(发生在app生命周期之外).
3.2.1 Understand the Trade-offs
3.2.2 Set a Repeating Alarm
3.2.3 Cancel an Alarm
```
if (alarmMgr != null) {
alarmMgr.cancel()
}
```
3.2.4 Start an Alarm When the Device Boots
- All alarms are canceled when a device shuts down.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- Implement a
BroadcastReceiver
to receiver the broadcast - Add the receiver to manifest file with an intent filter that filters on the
ACTION_BOOT_COMPLETED
action.