1. 前台服务 (Foreground Service)
代码示例
java
// 在 Service 的 onCreate 或 onStartCommand 中启动前台服务
public class MyForegroundService extends Service {
@Override
public void onCreate() {
super.onCreate();
// 创建通知渠道(Android 8.0+ 必需)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"channel_id", "My Foreground Service",
NotificationManager.IMPORTANCE_LOW
);
getSystemService(NotificationManager.class).createNotificationChannel(channel);
}
// 构建通知(Android 12+ 需指定 PendingIntent.FLAG_IMMUTABLE)
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
Notification notification = new NotificationCompat.Builder(this, "channel_id")
.setContentTitle("服务运行中")
.setContentText("正在执行后台任务...")
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent)
.build();
// 启动前台服务(ID 不可为 0)
startForeground(1, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 执行后台任务(如音乐播放或位置更新)
return START_STICKY;
}
}
注意事项
- Android 9+ 需在清单文件声明权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- Android 12+ 限制后台启动前台服务,需用户主动触发(如点击通知或应用可见)才能启动。
2. JobScheduler / WorkManager
代码示例(WorkManager)
java
// 定义 Worker 类
public class MyWorker extends Worker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Result doWork() {
// 执行后台任务(如数据同步)
return Result.success();
}
}
// 调度周期性任务(最小间隔 15 分钟)
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(false)
.build();
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
MyWorker.class, 15, TimeUnit.MINUTES
).setConstraints(constraints).build();
WorkManager.getInstance(context).enqueue(workRequest);
适用场景
- 日志上报:允许延迟执行的非实时任务。
- 数据预加载:在充电或空闲时触发。
3. 粘性服务 (Sticky Service)
代码示例
java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 执行任务后返回 START_STICKY
return START_STICKY; // 或 START_REDELIVER_INTENT
}
局限性
- Android 8.0+ 系统会在几分钟后强制停止空闲后台服务。
- 重启服务可能延迟数秒至数分钟,无法保证实时性。
4. 双进程守护
实现框架
-
声明两个 Service
xml<service android:name=".ServiceA" android:process=":processA" /> <service android:name=".ServiceB" android:process=":processB" />
-
互相监听存活状态
java// 在 ServiceA 中 private void startServiceB() { if (!isServiceRunning("ServiceB")) { startService(new Intent(this, ServiceB.class)); } } // 定时检查 ServiceB 是否存活(如每 30 秒一次)
风险提示
- Android 8.0+ 限制后台启动服务,需改用
startForegroundService()
并显示通知。 - 厂商 ROM 可能直接杀死整个应用进程组。
5. 系统广播唤醒
动态注册广播示例
java
// 在 Service 或 Application 中注册
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
// 屏幕亮起时重启服务
startService(new Intent(context, MyService.class));
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(receiver, filter); // 需在 onDestroy 时 unregisterReceiver
限制条件
- Android 7.0+ 对
CONNECTIVITY_ACTION
等广播仅支持动态注册。 - 避免滥用
ACTION_BOOT_COMPLETED
(用户可能禁用自启动权限)。
6. 账户同步机制 (Account Sync)
核心步骤
-
创建账户认证器
xml<!-- res/xml/syncadapter.xml --> <sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="com.example.provider" android:accountType="com.example.account" android:userVisible="true" android:supportsUploading="true" />
-
触发同步
javaAccount account = new Account("user", "com.example.account"); ContentResolver.requestSync(account, "com.example.provider", new Bundle());
用户影响
- 需用户手动在系统设置中同意账户同步权限。
- 频繁同步可能导致账号被系统标记为异常。
7. 厂商白名单
跳转系统设置示例
java
// 跳转小米自启动管理
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"
));
startActivity(intent);
// 跳转华为电池优化设置
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
适配建议
- 检测是否在白名单中(可用
PowerManager.isIgnoringBatteryOptimizations()
)。 - 提供图文引导界面,帮助用户手动设置。
8. 其他黑科技
1像素 Activity 示例
java
// 在 Service 中启动透明 Activity
public class KeepAliveActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.setGravity(Gravity.START | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
params.width = 1;
params.height = 1;
params.x = 0;
params.y = 0;
window.setAttributes(params);
}
}
// 启动 Activity
Intent intent = new Intent(context, KeepAliveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
风险提示
- Android 10+ 限制后台启动 Activity,需用户手动点击。
- Google Play 可能拒绝上架使用此类技巧的应用。
最佳实践总结
-
合理使用前台服务
- 在通知中提供任务开关(如停止播放按钮)。
- 适配 Android 12+ 的
PendingIntent.FLAG_IMMUTABLE
。
-
结合 WorkManager 与 AlarmManager
java// 精确定时任务(Android 6.0+ 需使用 setExactAndAllowWhileIdle) AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); PendingIntent pendingIntent = ...; alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
-
监控进程生命周期
java// 在 Application 中监听进程终止 registerComponentCallbacks(new ComponentCallbacks2() { @Override public void onTrimMemory(int level) { if (level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { // 进程即将被终止,尝试保存状态 } } });
通过合法且低功耗的方案组合,平衡功能需求与系统限制,才是长效保活的关键。