Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android  Service 用法

Android 中 Service 用法和最佳实践

作者:学习使我健康

本文介绍了Android中Service的使用场景、启动方式、绑定方式、前台服务等,并提供了常见的代码示例和最佳实践,帮助开发者正确使用Service组件,避免踩坑,感兴趣的朋友跟随小编一起看看吧

这篇就讲一件事: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 用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文