(1)后台运行需求
推送消息/广告
播放音乐
数据同步/文件传输
用户活动跟踪、
定时任务/闹钟
内容提供者
(2)实现自动后台运行
Stikcy Service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY; // START_REDELIVER_INTENT;
}
静态注册BroadcastReceiver监听系统级事件
(3)禁用无用组件
/**
* 监听系统事件的receiver
*/
public class AutoStartReceiver extends BroadcastReceiver {
public AutoStartReceiver() {
}
/**
* 在不需要一个receiver时,可使用该接口disable掉,
* 这样当匹配IntentFilter的事件发生时,就不会再启动该控件了
* @param context
*/
public static void disable(Context context) {
ComponentName receiver = new ComponentName(context, AutoStartReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
@Override
public void onReceive(Context context, Intent intent) {
Log.i("Receiver", intent.getAction());
context.startService(new Intent(context, StickyService.class));
}
}
<receiver
android:name=".AutoStartReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.AIRPLANE_MODE"/>
</intent-filter>
</receiver>
(4)定时任务
Timer
Handler.postDelayed
AlarmManager(使用硬件时钟)
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
/**
* 启动一个一次性闹钟
* 即使被kill掉也可以发生
* @param context
*/
public static void startOneTimeAlarm(Context context) {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("action.startOneTimeAlarm");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, pendingIntent);
Log.i("alarm", "start");
}
@Override
public void onReceive(Context context, Intent intent) {
Log.i("alarm", intent.getAction());
// 再启动一个
// 一般情况下并不需要这么做循环,使用setRepeating即可。
// 但如果启动的闹钟要求精确时间,那么只能这么做,因为setRepeating不提供精确闹钟选项
startOneTimeAlarm(context);
}
}
(5)JobScheduler
对执行时机无需精确控制
需要特定情况满足才执行
只能动态注册
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobManager {
public static void schedule(Context context) {
ComponentName cn = new ComponentName(context, TestJobService.class);
JobInfo.Builder jb = new JobInfo.Builder(1, cn);
jb.setPeriodic(5000);
jb.setRequiresCharging(true);
JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int code = js.schedule(jb.build());
Log.i("Job", "schedule job result: " + code);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class TestJobService extends JobService {
public TestJobService() {
}
@Override
public boolean onStartJob(JobParameters params) {
Log.i("TJS", "real start job, id: " + params.getJobId());
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.i("TJS", "job stopped");
return false;
}
}
<service
android:name=".TestJobService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
(6)WakeLock
private void backgroundTask() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP, "StickyService");
wakeLock.acquire();
try {
Thread.sleep(30 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
wakeLock.release();
}
}
(7)监控电池状态
public class BatteryReceiver extends BroadcastReceiver {
public BatteryReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BATTERY_LOW.equals(action)) {
Log.i("Battery", "battery low");
} else if (Intent.ACTION_BATTERY_OKAY.equals(action)) {
Log.i("Battery", "battery ok");
} else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
Log.i("Battery", "battery level is: " + level);
}
}
}
<receiver
android:name=".BatteryReceiver"
android:enabled="true"
android:exported="true">
</receiver>
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(receiver, filter);
(8)Doze
6.0引入的打盹模式