当前位置: 首页 > news >正文

安卓之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 配合点

  1. 前台服务要求

    • 使用 startForeground() 需在 onStartCommand()5秒内 显示通知,否则 Android 8.0+ 会触发 ANR[citation:1]。
    • Android 14+ 需在 Manifest 声明 android:foregroundServiceType="dataSync" 及对应权限(如 FOREGROUND_SERVICE_DATA_SYNC)。
  2. 线程管理

    • onStartCommand() 中启动无限循环线程需谨慎:
      new Thread(() -> {while (true) { /* ... */ } // 需在 onDestroy() 中终止线程,否则内存泄漏!
      }).start();
      
  3. 服务重启策略

    • START_STICKY 适用于需自动重启的任务(如实时定位),但可能因频繁重启耗电[citation:9][citation:10]。
    • 非实时任务建议改用 WorkManager
  4. 注意点

  • onCreate():服务首次创建时初始化资源(一次性)。
  • onStartCommand():每次 startService() 调用时执行任务。
  • onDestroy():服务销毁时释放资源。
  • onBind():仅响应 bindService() 绑定请求(未使用可返回 null)。
http://www.dtcms.com/a/267849.html

相关文章:

  • QT 菜单栏设计使用方法
  • 基于AndServer的RPC架构:Android原生SO文件远程调用实战指南
  • Python 机器学习核心入门与实战进阶 Day 4 - 支持向量机(SVM)原理与分类实战
  • 深度学习图像分类数据集—蘑菇识别分类
  • plantuml用法总结
  • Java设计模式之行为型模式(策略模式)介绍与说明
  • 利用低空无人机影像进行树种实例分割
  • 深入解析Vue中v-model的双向绑定实现原理
  • 牛客周赛99
  • 关于 栈帧变化完整流程图(函数嵌套)
  • 大模型面试:RAG与Agent相关
  • 《Redis》集群
  • 【Note】《Kafka: The Definitive Guide》 第二章 Installing Kafka:Kafka 安装与运行
  • Redis--主从复制详解
  • 【Docker基础】Docker容器挂载方式深度解析:--volume与--mount参数对比
  • QT6 源(155)模型视图架构里的列表视图 QListView:接着学习成员函数,信号函数,附上本类的源代码带注释。
  • HCIA-网络地址转换(NAT)
  • CppCon 2018 学习:Woes of Scope Guards and Unique_Resource
  • 抖音小游戏(IAA)巨量引擎投放指南
  • [shadPS4] 内存管理 | 权限管理 |文件系统 | 挂载和句柄
  • 【BTC】数据结构
  • 7,TCP服务器
  • JavaScript基础语法之运算符和控制流
  • 李宏毅NLP-8-语音模型
  • 【管理学】组织纪律性与创新性的失衡导致的问题
  • Redis事务机制
  • [论文阅读]VGGFace2: A dataset for recognising faces across pose and age
  • Linux-磁盘管理
  • 【前端工程化】前端工作中的业务规范有哪些
  • 基于评估方法论评估一个大模型的准确度