01-Service基础与启动方式
1. Service 是什么
Service 是 Android 中用于执行后台或前台任务的应用组件。它没有自己的 UI,可以在用户离开某个 Activity 后继续运行某些工作。
但是要注意:
Service 不是线程。
Service 默认运行在应用进程的主线程中。
Service 不会自动帮你创建子线程。所以 Service 中不能直接执行耗时操作,否则可能导致 ANR。
正确理解:
Service = 组件生命周期与系统入口
Thread/Coroutine/Executor = 真正执行耗时任务的并发工具2. Service 与 Thread 的区别
示例:Service 内部开启协程处理任务:
class SyncService : Service() {
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
serviceScope.launch {
try {
syncData()
} finally {
stopSelf(startId)
}
}
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onDestroy() {
serviceScope.cancel()
super.onDestroy()
}
}3. Service 的类型
现代 Android 中,可以从使用场景上分为:
4. 在 Manifest 中声明 Service
<service
android:name=".SyncService"
android:exported="false" />如果是前台服务,还需要声明权限和类型,例如媒体播放:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<application ...>
<service
android:name=".MusicService"
android:exported="false"
android:foregroundServiceType="mediaPlayback" />
</application>5. startService 启动方式
启动:
val intent = Intent(this, SyncService::class.java)
startService(intent)Service 中处理:
class SyncService : Service() {
override fun onCreate() {
super.onCreate()
// 只在 Service 首次创建时调用一次
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// 每次 startService 都会回调这里
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onDestroy() {
// 清理资源
super.onDestroy()
}
}停止:
stopService(Intent(this, SyncService::class.java))或者 Service 内部:
stopSelf()
stopSelf(startId)6. bindService 启动方式
Bound Service 适合让 Activity 调用 Service 中的方法。
Service:
class PlayerService : Service() {
inner class LocalBinder : Binder() {
fun getService(): PlayerService = this@PlayerService
}
private val binder = LocalBinder()
override fun onBind(intent: Intent): IBinder {
return binder
}
fun play() {
// 播放音乐
}
fun pause() {
// 暂停音乐
}
}Activity:
class MainActivity : AppCompatActivity() {
private var service: PlayerService? = null
private var bound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
val localBinder = binder as PlayerService.LocalBinder
service = localBinder.getService()
bound = true
}
override fun onServiceDisconnected(name: ComponentName?) {
bound = false
service = null
}
}
override fun onStart() {
super.onStart()
bindService(
Intent(this, PlayerService::class.java),
connection,
Context.BIND_AUTO_CREATE
)
}
override fun onStop() {
if (bound) {
unbindService(connection)
bound = false
}
super.onStop()
}
}7. onStartCommand 返回值
onStartCommand() 必须返回一个整型常量,告诉系统 Service 被杀后如何处理。
8. 面试回答模板
问题:Service 和 Thread 有什么区别?
可以这样回答:
Service 是 Android 组件,用来承载后台或前台任务的生命周期和系统入口;Thread 是执行代码的线程。Service 默认运行在主线程,不会自动开子线程,所以耗时操作仍然要自己放到 Thread、线程池或协程中执行。Service 可以在 Activity 销毁后继续运行,但并不意味着它适合所有后台任务,Android 8.0 以后后台服务受到限制,很多延迟任务应该用 WorkManager。