it编程 > App开发 > Android

Android 中 Service 用法和最佳实践

21人参与 2026-04-27 Android

这篇就讲一件事:service 到底什么时候用,怎么用,怎么不踩坑

你可以先把 service 理解成:
“app 没有页面展示时,仍然需要在后台继续干活的一个组件”。
就像关注博主,下次容易找到一样。
点点关注一下
常见场景:

1. 先记住这 3 句话

  1. service 不是线程,它默认也跑在主线程。
  2. 耗时任务不能直接写在 service 里,不然容易 anr。
  3. 真正长期运行的后台任务,通常要做成前台服务(带通知)。

2. service 有两种常用玩法

简单说:

2.1 启动式 service(started service)

启动方式:

适合场景:

核心回调:

停止方式:

2.2 绑定式 service(bound service)

绑定方式:bindservice(intent, conn, flags)

适合场景:

核心回调:

一句话理解:
页面拿到 ibinder 后,就能像调用普通对象一样调用服务方法。

3. 生命周期怎么理解更简单

启动式

oncreate() -> onstartcommand()(可能多次)-> ondestroy()

onstartcommand() 返回值怎么选:

绑定式

oncreate() -> onbind() -> 交互 -> onunbind() -> ondestroy()

4. 什么是前台服务(foreground service)

你可以把前台服务理解成:
“系统允许你长时间后台运行,但你必须给用户一个持续通知,告诉用户你在做什么。”

从 android 8 开始,后台限制变严格,很多长期任务都要走前台服务。

基本要求:

  1. startforegroundservice(intent) 启动
  2. 很快调用 startforeground(notificationid, notification)
  3. 通知必须可见(不能偷偷跑)

android 14+ 额外注意:

5. 代码示例(可直接参考)

5.1 启动式 service(kotlin)

class syncservice : service() {
    private val scope = coroutinescope(supervisorjob() + dispatchers.io)
    override fun oncreate() {
        super.oncreate()
        // 初始化资源
    }
    override fun onstartcommand(intent: intent?, flags: int, startid: int): int {
        scope.launch {
            try {
                // 执行耗时任务
                dosync()
            } finally {
                // 任务结束后停止服务
                stopself(startid)
            }
        }
        return start_not_sticky
    }
    override fun onbind(intent: intent?): ibinder? = null
    override fun ondestroy() {
        super.ondestroy()
        scope.cancel()
    }
    private suspend fun dosync() {
        // todo: 执行同步逻辑
    }
}

启动和停止:

contextcompat.startforegroundservice(context, intent(context, syncservice::class.java))
// 或 context.startservice(intent)(低版本或非前台需求)
context.stopservice(intent(context, syncservice::class.java))

5.2 绑定式 service(kotlin)

class musicservice : service() {
    private val binder = localbinder()
    inner class localbinder : binder() {
        fun getservice(): musicservice = this@musicservice
    }
    override fun onbind(intent: intent): ibinder = binder
    fun play() {
        // 播放逻辑
    }
    fun pause() {
        // 暂停逻辑
    }
}

activity 绑定:

class mainactivity : appcompatactivity() {
    private var musicservice: musicservice? = null
    private var bound = false
    private val conn = object : serviceconnection {
        override fun onserviceconnected(name: componentname?, service: ibinder?) {
            val binder = service as musicservice.localbinder
            musicservice = binder.getservice()
            bound = true
        }
        override fun onservicedisconnected(name: componentname?) {
            bound = false
            musicservice = null
        }
    }
    override fun onstart() {
        super.onstart()
        bindservice(
            intent(this, musicservice::class.java),
            conn,
            context.bind_auto_create
        )
    }
    override fun onstop() {
        super.onstop()
        if (bound) {
            unbindservice(conn)
            bound = false
        }
    }
}

6. manifest 配置

<service
    android:name=".service.musicservice"
    android:exported="false"
    android:foregroundservicetype="mediaplayback" />

说明:

7. 到底该不该用 service

这些情况适合用 service

这些情况不建议直接用 service

8. 常见问题与最佳实践

9. 一句话总结

service 适合“没页面但要持续干活”的任务:
只管执行用启动式,需要交互控制用绑定式,长期后台任务优先做前台服务并按系统版本补齐权限和类型声明。

到此这篇关于android 中 service 用法的文章就介绍到这了,更多相关android service 用法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

Android BLE 的 notify 和 indicate区别解析

04-27

uni-app Android离线打包的多环境配置方案

04-28

PyTorch模型转TensorFlow Lite的Android部署全流程指南

04-24

将PyTorch模型部署到Android的全流程指南

04-22

Android WebView版本升级方案对比及注意事项详解

04-08

Android手游SDK组件化开发详细实战指南

03-10

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论