安卓之service
在Android中,APK中的Service可以是前台服务或后台服务,具体由开发者决定其运行方式。
1、前台后台服务
一、前台服务 vs 后台服务的核心区别
特性 前台服务 后台服务
用户可见性 必须显示持续通知(用户可见) 无通知,用户不可见
系统优先级 高优先级,不易被系统回收 低优先级,易被系统回收(尤其内存不足时)
资源限制 受较宽松的限制(如Android 8.0+允许长期运行) 受严格限制(如Android 8.0+限制后台执行时间)
典型用途 音乐播放、导航、实时监控等关键任务 数据同步、日志收集等非关键任务
稳定性 更稳定,适合长期运行 易被系统终止,适合短暂任务
二、系统对两者的处理策略
前台服务:
必须显示通知:通过startForeground()方法启动,并关联一个Notification。
高优先级:系统会尽量保留前台服务,避免其被回收。
兼容性:Android 8.0+要求前台服务必须声明FOREGROUND_SERVICE权限。
后台服务:
无通知:通过startService()启动,用户不可见。
严格限制:
Android 8.0+:后台服务运行时间受限(如10分钟内),超时后可能被终止。
Android 10+:进一步限制后台启动Activity的能力。
替代方案:
使用WorkManager处理延迟任务。
使用JobScheduler或AlarmManager调度周期性任务。
三、决定Service是前台还是后台的关键因素
启动方式:
前台服务:调用startForegroundService(),并在5秒内调用startForeground()显示通知。
后台服务:调用startService(),不显示通知。
系统资源管理:
前台服务会占用通知栏资源,但换取更高的稳定性。
后台服务不占用通知栏,但易被系统终止。
代码实现示例:
前台服务:
public class ForegroundService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Notification notification = new NotificationCompat.Builder(this, "channel_id").setContentTitle("前台服务").setContentText("正在运行").setSmallIcon(R.drawable.ic_notification).build();startForeground(1, notification); // 关键:转为前台服务return START_STICKY;}
}
后台服务:
public class BackgroundService extends Service {@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 执行后台任务(无通知)return START_NOT_STICKY; // 非关键任务,系统终止后不重启}
}
四、注意
关键任务用前台服务:
如音乐播放、实时定位等,需通过通知告知用户。
非关键任务用后台服务或替代方案:
如数据同步,可用WorkManager处理。
总结
前台服务:高优先级、用户可见、适合长期任务,但需显示通知。
后台服务:低优先级、用户不可见、适合短暂任务,但易被系统终止。
决定因素:启动方式(startForegroundService() vs startService())及系统资源管理策略。
2 、调试命令
一、查看是否存在这个服务依赖的apk
pm list packages | grep myapplication
二、 开始服务
前台服务
adb shell am startservice -n <包名>/<服务类全路径>adb shell am startservice -n com.example.myapplication/.MyForegroundService
后台服务
adb shell am start-foreground-service -n com.example.myapplication/.MyForegroundService
三、结束服务
am stop-service -n com.example.myapplication/.MyForegroundService
四、打印服务状态
dumpsys activity services | grep "com.example.myapplication/.MyForegroundService"
注意:
当使用上面的 stop-service 的时候,可能不会打印
public void onDestroy() {super.onDestroy();android.util.Log.e("MyService", "fln stop");}
因为会 命令会kill 掉
3、.继承 service 的子类
在 Android Service 的生命周期中,onCreate()
、onStartCommand()
、onDestroy()
和 onBind()
的调用时机取决于服务的启动方式(启动模式或绑定模式)。以下结合你的代码和 Android 机制进行详细说明:
一. 核心生命周期方法调用时机
(1) onCreate()
- 调用时机:
仅当 Service 首次创建时调用一次(无论通过startService()
或bindService()
启动)。若服务已存在,后续启动不会重复调用[citation:1][citation:3][citation:9]。 - 用途:
初始化资源(如数据库、线程、通知渠道等)。 - 代码示例:
@Override public void onCreate() {super.onCreate();createNotificationChannel(); // 初始化通知渠道(仅执行一次) }
(2) onStartCommand()
- 调用时机:
每次通过startService()
启动服务时调用(无论服务是否已存在)[citation:1][citation:9][citation:10]。 - 用途:
执行后台任务(如下载、轮询),并返回START_STICKY
等标志控制服务被杀死后的行为。 - 代码示例:
@Override public int onStartCommand(Intent intent, int flags, int startId) {// 创建前台通知并启动线程startForeground(NOTIFICATION_ID, notification); new Thread(() -> { /* 后台任务 */ }).start();return START_STICKY; // 服务被杀死后自动重启 }
(3) onDestroy()
- 调用时机:
服务被销毁时调用(主动调用stopService()
/stopSelf()
,或绑定模式下所有客户端解绑)[citation:1][citation:3][citation:12]。 - 用途:
释放资源(如停止线程、注销监听器)。 - 代码示例:
@Override public void onDestroy() {super.onDestroy();Log.e("MyService", "Service stopped"); // 记录销毁日志 }
(4) onBind()
- 调用时机:
当组件通过bindService()
绑定到服务时调用(若服务未运行,会先触发onCreate()
)[citation:3][citation:11]。 - 用途:
返回IBinder
接口供客户端与服务交互(如跨进程通信)。 - 代码示例:
@Override public IBinder onBind(Intent intent) {return null; // 你的代码未支持绑定模式,故返回 null }
二. 不同启动模式下的生命周期流程
启动模式(通过 startService()
)
绑定模式(通过 bindService()
)
⚠️ 注意:若服务同时通过
startService()
启动和bindService()
绑定,需两者均终止(stopService()
+ 所有解绑)才会触发onDestroy()
[citation:3][citation:11]。
三 .Manifest 配合点
-
前台服务要求:
- 使用
startForeground()
需在onStartCommand()
中 5秒内 显示通知,否则 Android 8.0+ 会触发ANR
[citation:1]。 - Android 14+ 需在 Manifest 声明
android:foregroundServiceType="dataSync"
及对应权限(如FOREGROUND_SERVICE_DATA_SYNC
)。
- 使用
-
线程管理:
- 在
onStartCommand()
中启动无限循环线程需谨慎:new Thread(() -> {while (true) { /* ... */ } // 需在 onDestroy() 中终止线程,否则内存泄漏! }).start();
- 在
-
服务重启策略:
START_STICKY
适用于需自动重启的任务(如实时定位),但可能因频繁重启耗电[citation:9][citation:10]。- 非实时任务建议改用
WorkManager
。
-
注意点
onCreate()
:服务首次创建时初始化资源(一次性)。onStartCommand()
:每次startService()
调用时执行任务。onDestroy()
:服务销毁时释放资源。onBind()
:仅响应bindService()
绑定请求(未使用可返回null
)。