Services
1. Giới thiệu
Phần tiêu đề “1. Giới thiệu”Service là component chạy background, không có UI, thực hiện long-running operations.
2. Loại Services
Phần tiêu đề “2. Loại Services”| Type | Description | Thread |
|---|---|---|
| Foreground | Visible notification, user aware | Main (cần background thread) |
| Background | No notification, limited | Main |
| Bound | Client-server, IPC | Main |
3. Foreground Service
Phần tiêu đề “3. Foreground Service”Khai báo trong Manifest
Phần tiêu đề “Khai báo trong Manifest”<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<service android:name=".MusicService" android:foregroundServiceType="mediaPlayback" android:exported="false" />Implementation
Phần tiêu đề “Implementation”class MusicService : Service() {
override fun onCreate() { super.onCreate() }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val notification = createNotification()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { startForeground( NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK ) } else { startForeground(NOTIFICATION_ID, notification) }
// Do work in background thread CoroutineScope(Dispatchers.IO).launch { playMusic() }
return START_STICKY }
override fun onBind(intent: Intent?): IBinder? = null
override fun onDestroy() { super.onDestroy() stopMusic() }
private fun createNotification(): Notification { val channelId = createNotificationChannel()
return NotificationCompat.Builder(this, channelId) .setContentTitle("Playing Music") .setContentText("Song name") .setSmallIcon(R.drawable.ic_music) .setPriority(NotificationCompat.PRIORITY_LOW) .build() }}Start/Stop Service
Phần tiêu đề “Start/Stop Service”// Startval intent = Intent(context, MusicService::class.java)if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(intent)} else { context.startService(intent)}
// Stopcontext.stopService(Intent(context, MusicService::class.java))4. Bound Service
Phần tiêu đề “4. Bound Service”class DownloadService : Service() {
private val binder = LocalBinder()
inner class LocalBinder : Binder() { fun getService(): DownloadService = this@DownloadService }
override fun onBind(intent: Intent): IBinder = binder
fun downloadFile(url: String) { // Download logic }}
// Activity bindingclass MainActivity : ComponentActivity() { private var downloadService: DownloadService? = null private var isBound = false
private val connection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { val binder = service as DownloadService.LocalBinder downloadService = binder.getService() isBound = true }
override fun onServiceDisconnected(name: ComponentName?) { isBound = false } }
override fun onStart() { super.onStart() Intent(this, DownloadService::class.java).also { intent -> bindService(intent, connection, Context.BIND_AUTO_CREATE) } }
override fun onStop() { super.onStop() if (isBound) { unbindService(connection) isBound = false } }}5. onStartCommand Return Values
Phần tiêu đề “5. onStartCommand Return Values”| Value | Behavior |
|---|---|
START_STICKY |
Recreate if killed, null intent |
START_NOT_STICKY |
Don’t recreate |
START_REDELIVER_INTENT |
Recreate with last intent |
6. Service Lifecycle
Phần tiêu đề “6. Service Lifecycle”startService() → onCreate() → onStartCommand() → Running → onDestroy() ↑startService() again → ──────────────────┘
bindService() → onCreate() → onBind() → Bound → onUnbind() → onDestroy()7. Service với Coroutines
Phần tiêu đề “7. Service với Coroutines”class MyService : Service() {
private val job = SupervisorJob() private val scope = CoroutineScope(Dispatchers.IO + job)
override fun onStartCommand(...): Int { scope.launch { doWork() } return START_NOT_STICKY }
override fun onDestroy() { super.onDestroy() job.cancel() }}8. Android 14+ Restrictions
Phần tiêu đề “8. Android 14+ Restrictions”// Android 14+ cần type cụ thể<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Khi nào dùng | Solution |
|---|---|
| Long task, user aware | Foreground Service |
| Short task | WorkManager |
| Client-server | Bound Service |
| Periodic sync | WorkManager |