21人参与 • 2026-04-27 • Android
这篇就讲一件事:service 到底什么时候用,怎么用,怎么不踩坑。
你可以先把 service 理解成:
“app 没有页面展示时,仍然需要在后台继续干活的一个组件”。
就像关注博主,下次容易找到一样。
点点关注一下
常见场景:
service 不是线程,它默认也跑在主线程。service 里,不然容易 anr。简单说:
启动方式:
startservice(intent)(老方式)startforegroundservice(intent)(配合前台服务)适合场景:
核心回调:
oncreate():第一次创建时调用一次onstartcommand():每次启动都会进来ondestroy():销毁时调用停止方式:
stopself()stopservice(intent)绑定方式:bindservice(intent, conn, flags)
适合场景:
核心回调:
oncreate()onbind()(返回 ibinder)onunbind() / onrebind()ondestroy()一句话理解:
页面拿到 ibinder 后,就能像调用普通对象一样调用服务方法。
oncreate() -> onstartcommand()(可能多次)-> ondestroy()
onstartcommand() 返回值怎么选:
start_not_sticky:被系统杀了就算了,不自动重建(一次性任务常用)start_sticky:系统尽量拉起来,但 intent 可能没了start_redeliver_intent:系统重建时,把上次 intent 再给你一次oncreate() -> onbind() -> 交互 -> onunbind() -> ondestroy()
你可以把前台服务理解成:
“系统允许你长时间后台运行,但你必须给用户一个持续通知,告诉用户你在做什么。”
从 android 8 开始,后台限制变严格,很多长期任务都要走前台服务。
基本要求:
startforegroundservice(intent) 启动startforeground(notificationid, notification)android 14+ 额外注意:
manifest 里写 foregroundservicetypemediaplayback、location、datasync)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))
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
}
}
}<service
android:name=".service.musicservice"
android:exported="false"
android:foregroundservicetype="mediaplayback" />说明:
android:exported="false":只给自己 app 用,默认更安全exported="true",并加权限保护这些情况适合用 service:
这些情况不建议直接用 service:
workmanagerservice 默认是主线程,耗时操作请放协程/线程池。stopself(),别让服务白跑。onstartcommand() 返回值,并做好状态恢复。service 适合“没页面但要持续干活”的任务:
只管执行用启动式,需要交互控制用绑定式,长期后台任务优先做前台服务并按系统版本补齐权限和类型声明。
到此这篇关于android 中 service 用法的文章就介绍到这了,更多相关android service 用法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论