Android: Service基本使用

Service 是 Android 四大组件之一。是实现程序后台运行的解决方案。

默认是运行主线程中。

基本使用流程

  1. 自定义 Service 继承 Service() 类, 必须重写唯一抽象方法 onBind()
  2. 为了 完成事情逻辑的处理,一般会重写 onCreate(), onStartCommand(), onDestroy() 方法
  3. 在 AndroidManifest.xml 中注册

分支一:启动、停止Service

  1. 使用显式 Intent 绑定自定义的Service;使用startService(intent)来启动Service

  2. 使用显式 Intent 绑定自定义的Service;使用stopService(intent)来停止Service

分支二:Activity 和 Service 进行通信--- Bind Service 的方式,让 Service 从一个"后台默默干活"的组件,变成一个"可以被前端控制"的对象。

  1. 自定义 Service
  • 内部创建 Binder 子类,用于暴露 Service 中需要被 Activity 调用的方法。

  • 重写 onBind(),返回该 Binder 实例。

  1. Activity 端
  • 实现 ServiceConnection 接口,重写 onServiceConnected (绑定时调用,里面有Binder类型的参数) 和 onServiceDisconnected (解绑时调用)。

  • 使用显式 Intent (指定 Service 的类名)调用 bindService()

  • 在适当生命周期(如 onDestroy)调用 unbindService() 解绑。

Service 的生命周期

  • 整体生命周期回调onCreate(), onStartCommand(), onBind(), onUnbind(), onDestroy()
    启动式:
text 复制代码
调用startService()方法 → onCreate() → onStartCommand() → ... → 调用stopService()/stopSelf()方法 → onDestroy()

需要注意的是,每次 startService(), onStartCommand() 都会执行,但是只有Service之前没有创建过,onCreate才会执行。

每个进程中每个Service只会存在一个实例,因此无论调用多少次 startService(),一次 stopService()/stopSelf()方法 Service 就会停止。

绑定式:

text 复制代码
调用bindService()方法 → onCreate() → onBind() → ... → 调用unbindService()方法 → onUnbind() → onDestroy()

销毁条件所有客户端都解绑 后,Service 会立即调用 onDestroy() 销毁(前提是没有被 startService 启动过)

onBind 只调用一次(除非 Service 被销毁重建) ,当第一个客户端绑定后,后续客户端再调用 bindService,如果 Service 当前还有其他客户端连着,则没有任何生命周期回调。

  • 当第一个客户端调用 bindService() 时,系统会:

    1. 检查该 Service 是否已启动(没有则调用 onCreate()

    2. 调用 onBind() 获取 IBinder 对象并返回给客户端

    3. 将这个 IBinder 缓存起来

  • 当第二个、第三个客户端再调用 bindService() 绑定同一个 Service(实例未销毁)时:

    • 系统直接复用之前缓存的 IBinder 对象

    • 不会再调用 onBind()

    • 新客户端直接获得那个 IBinder,可以立即与 Service 通信

混合式:

text 复制代码
startService()      → onCreate() → onStartCommand()
bindService()       → onBind()   (此时 Service 继续运行)
unbindService()     → onUnbind()  (但 Service 不会销毁,因为之前 startService 了)
stopService()       → onDestroy()

只有都解绑,或者停止后,才会onDestroy()回调。


前台Service

从 Android8.0 开始,只有前台可见的情况下,Service才能稳定运行,否则可能随时被系统回收。

为了使 Service 能够一直保持运行状态,使用通知的方式,将Service一直以通知的形式在状态栏显示,即保持在前台显示,以确保系统不会回收 Service。

可以视为: Service + 通知 + 权限声明

这里不是以 manager.notify(1, notification) 来显示通知,而是在 Service 中 onCreate 使用 startForeground(1,notification) 来显示前台 Service。

此次前台Service 需要 进行权限声明


多线程使用Service

因为Service默认是运行在主线程的,而Service一般会处理一些耗时逻辑,例如下载,很容易出现ANR(Application Not Responding)。 因此需要用到多线程技术.

方式:

  1. 在Service的每个具体方法开启一个子线程。例如 thread{}
  2. 执行完逻辑后在 thread{} 中使用stopSelf()、stopService() 停止 Service 防止一直处于运行状态消耗系统资源

IntentService 是上述逻辑的一种Service封装类。

相关推荐
墨狂之逸才12 小时前
Android TV WebView 遥控器按键处理:从全透传到白名单
android
plainGeekDev17 小时前
MVC 写法 → MVVM
android·java·kotlin
恋猫de小郭18 小时前
Flutter Patchwork,不用 Fork 改依赖包源码的第三方工具
android·前端·flutter
三少爷的鞋19 小时前
“结构化”这个词,本质上就是——把混乱的东西变成有组织、有规则、有边界的东西
android
方白羽1 天前
Android Gradle 缓存与文件目录深度解析
android·gradle·android studio
曲幽2 天前
Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招!
android·termux·nohup·services·wake-lock
plainGeekDev2 天前
单例模式 → object 声明
android·java·kotlin
程序员陆业聪2 天前
读者点单·03|Compose 与传统 View 混用的 12 个真实坑
android
程序员陆业聪2 天前
读者点单·02|Android 启动优化实战:Trace 抓取→Application 编排→冷启动全流程拆解
android
Coffeeee2 天前
帮你快速理解AI Agent之我想招个Android实习生
android·人工智能·agent