Background Service — định nghĩa, loại và cách hoạt động trong Android

Tác giả: IT Sectr Đã đăng: 2026-03-27 Thời gian đọc: 8 phút

Background Service là một thành phần Android được thiết kế để thực hiện các thao tác dài trong nền mà không có giao diện người dùng. Không giống Activity, Service tiếp tục hoạt động ngay cả sau khi ứng dụng được thu nhỏ hoặc người dùng chuyển sang ứng dụng khác. Theo Android Developers, 2026, có ba loại dịch vụ: Started Service, Bound Service và Foreground Service, mỗi loại có vòng đời và phạm vi ứng dụng riêng.

Điểm chính

  • Background Service là thành phần Android cho các thao tác nền không có UI, hoạt động độc lập với mọi activity.
  • Started Service được khởi chạy qua startService và chạy cho đến khi dừng rõ ràng qua stopSelf.
  • Bound Service liên kết với một thành phần qua bindService và tồn tại chừng nào còn client kết nối.
  • Foreground Service hiển thị thông báo liên tục và không bị hệ thống tiêu diệt khi pin yếu.
  • Từ Android 8, các dịch vụ nền có giới hạn nghiêm ngặt về khởi động trong nền.

Background Service trong Android là gì?

Background Service (hay đơn giản là Service) là một trong bốn thành phần cơ bản của ứng dụng Android, cùng với Activity, BroadcastReceiver và ContentProvider. Không giống Activity, Service không có giao diện trực quan và được thiết kế để thực hiện các thao tác phải tiếp tục bất kể ứng dụng có ở tiền cảnh hay không.

Service chạy trên luồng chính của ứng dụng, vì vậy mọi thao tác chặn bên trong nó đều yêu cầu tạo một luồng riêng. Nếu không làm điều này, hệ thống sẽ gửi ANR (Application Not Responding). Đối với các thao tác nền đơn giản, Android cung cấp IntentService, tự động tạo một luồng công việc. Trong các dự án hiện đại, nên sử dụng coroutine Kotlin với CoroutineScope bên trong Service để xử lý bất đồng bộ mà không chặn luồng chính.

Mục đích chính của Service là phát nhạc, tải tệp, xử lý yêu cầu mạng, đồng bộ dữ liệu và các tác vụ khác phải tiếp tục sau khi người dùng rời ứng dụng. Tuy nhiên, từ Android 8, các nhà phát triển phải lựa chọn cẩn thận giữa các loại dịch vụ, tính đến các giới hạn của công việc nền.

Vòng đời Service hoạt động như thế nào?

Service có vòng đời riêng, khác với Activity. Nó bao gồm bốn phương thức chính: onCreate, onStartCommand, onBind và onDestroy. Hiểu được chu trình này là điều cần thiết để triển khai các tác vụ nền mà không bị rò rỉ bộ nhớ.

onCreate và onStartCommand

Phương thức onCreate được gọi khi dịch vụ được tạo, một lần trong suốt vòng đời của nó. Tại đây, các tài nguyên như bộ đếm thời gian, kết nối cơ sở dữ liệu và socket được khởi tạo. Phương thức onStartCommand được gọi mỗi khi startService được gọi, cho phép gửi lệnh đến một dịch vụ đang chạy. Giá trị trả về xác định hành vi của hệ thống khi khởi động lại.

kotlin
class DownloadService : Service() {

    override fun onCreate() {
        super.onCreate()
        initializeDownloader()
    }

    override fun onStartCommand(
        intent: Intent?,
        flags: Int,
        startId: Int
    ): Int {
        downloadFile(intent?.getStringExtra("url"))
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? = null
}

onBind và onDestroy

onBind được gọi khi liên kết một dịch vụ qua bindService và trả về một đối tượng IBinder để tương tác với client. Phương thức này chỉ được sử dụng cho Bound Service. onDestroy là lệnh gọi cuối cùng trước khi dịch vụ bị hủy. Tại đây, mọi tài nguyên được giải phóng, luồng được dừng và tác vụ bị hủy.

Các loại dịch vụ nền

Android cung cấp ba loại Service, mỗi loại được thiết kế cho kịch bản riêng. Chọn sai loại có thể dẫn đến hành vi ứng dụng không ổn định hoặc tiêu hao pin.

Started Service

Started Service được khởi chạy bằng cách gọi startService và chạy cho đến khi gọi stopSelf hoặc stopService. Nó phù hợp với các tác vụ cần thực hiện ngay lập tức: gửi phân tích, xử lý hình ảnh, tải một tệp duy nhất. Sau khi hoàn thành công việc, dịch vụ tự dừng.

Bound Service

Bound Service cung cấp giao diện client-server, cho phép Activity, Fragment hoặc thành phần khác tương tác với dịch vụ. Dịch vụ tồn tại chừng nào có ít nhất một client liên kết. Khi tất cả client hủy liên kết, dịch vụ bị hủy. Bound Service hữu ích cho các tác vụ yêu cầu giao tiếp hai chiều: trình phát nhạc, dẫn đường.

Foreground Service

Foreground Service là Started Service có thông báo liên tục trên thanh trạng thái. Hệ thống coi dịch vụ như vậy là đang hoạt động và không tiêu diệt nó ngay cả khi thiếu bộ nhớ. Foreground Service là bắt buộc đối với phát nhạc, ghi âm, theo dõi vị trí và các tác vụ quan trọng khác cho người dùng.

Tham sốStartedBoundForeground
Khởi độngstartServicebindServicestartForeground
Tuổi thọđến stopSelfchừng nào còn clientđến stopForeground
Thông báokhôngkhôngbắt buộc
Có thể bị tiêu diệtkhông
Ví dụtải xuốngtrình phátnhạc

Tạo và chạy Service

Tạo một dịch vụ bắt đầu bằng khai báo một lớp kế thừa từ Service và đăng ký nó trong AndroidManifest.xml. Không có đăng ký trong tệp kê khai, hệ thống sẽ không thể khởi động dịch vụ và mọi lệnh gọi startService sẽ gây ra ngoại lệ.

kotlin
// Đăng ký trong AndroidManifest.xml
@SuppressLint("ForegroundServiceType")
class SyncService : Service() {

    override fun onStartCommand(
        intent: Intent?,
        flags: Int,
        startId: Int
    ): Int {
        startForeground(
            NOTIFICATION_ID,
            createNotification()
        )
        performSync(intent)
        return START_NOT_STICKY
    }
}

Để khởi động một dịch vụ từ Activity hoặc Fragment, một Intent với tham chiếu rõ ràng đến lớp dịch vụ được sử dụng. Từ Android 8, Foreground Service yêu cầu quyền FOREGROUND_SERVICE trong tệp kê khai.

kotlin
// Khởi động Started Service
val intent = Intent(this, SyncService::class.java)
intent.putExtra("action", "sync")
startService(intent)

// Khởi động Foreground Service (Android 8+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent)
} else {
    startService(intent)
}

Giới hạn trong Android 8+

Từ Android 8 (API 26), Google đã đưa ra các giới hạn nghiêm ngặt đối với các dịch vụ nền. Việc khởi động dịch vụ nền (khi ứng dụng không ở tiền cảnh) chỉ được phép trong các trường hợp ngoại lệ: khi nhận thông báo push, sau khi thiết bị khởi động hoặc qua JobScheduler.

Đối với các tác vụ dài không cần thực hiện ngay, nên sử dụng WorkManager hoặc JobScheduler. Nếu một ứng dụng thực sự cần một dịch vụ đang chạy, cách duy nhất là Foreground Service với thông báo mà người dùng có thể thấy. Việc khởi động một dịch vụ không có thông báo trong nền sẽ bị hệ thống bỏ qua.

JobIntentService để tương thích ngược

JobIntentService là một lớp chuyên dụng xuất hiện trong thư viện hỗ trợ để hoạt động trên Android 5+. Nó kết hợp hành vi của IntentService (luồng công việc tự động, xử lý tuần tự) với lập lịch qua JobScheduler. Trên Android 8+, JobIntentService sử dụng JobScheduler nội bộ, và trên các phiên bản cũ hơn, một Service thông thường. Điều này cho phép xử lý thống nhất các tác vụ nền mà không cần kiểm tra phiên bản Android bổ sung.

kotlin
class UploadJobService : JobIntentService() {

    companion object {
        private const val JOB_ID = 1000

        fun enqueueWork(context: Context, work: Intent) {
            enqueueWork(
                context,
                UploadJobService::class.java,
                JOB_ID,
                work
            )
        }
    }

    override fun onHandleWork(intent: Intent) {
        val fileUri = intent.getStringExtra("file_uri")
        // Chạy trong một luồng nền
        uploadFile(fileUri)
    }
}

Quản lý bộ nhớ và rò rỉ trong Service

Một trong những vấn đề thường gặp khi làm việc với Background Service là rò rỉ bộ nhớ. Vì Service có thể sống lâu hơn Activity, các tham chiếu đến Activity bên trong Service (qua listener, callback hoặc broadcast) ngăn việc thu gom rác của các thành phần UI. Nên sử dụng WeakReference, ViewModel hoặc LiveData để giao tiếp Service với UI. Trong onDestroy, nhớ hủy tất cả đăng ký, dừng luồng và đóng con trỏ.

Service và WorkManager: khi nào chọn gì

Sự lựa chọn giữa Background Service và WorkManager phụ thuộc vào kịch bản. Service phù hợp cho các tác vụ phải chạy ngay lập tức và liên tục: phát nhạc, ghi âm, theo dõi GPS. WorkManager tốt hơn cho các tác vụ trì hoãn, được đảm bảo: đồng bộ, gửi phân tích, tải log. WorkManager sống sót qua khởi động lại thiết bị, còn Service thì không. Service có thể là Foreground với thông báo, trong khi WorkManager lặng lẽ trong nền. Trong thực tế, các nhà phát triển kết hợp cả hai: Foreground Service cho các tác vụ quan trọng với người dùng và WorkManager cho bảo trì nền.

Android 12 đã giới thiệu cờ android:foregroundServiceType, yêu cầu chỉ định loại dịch vụ: dataSync, camera, connectedDevice, location, mediaPlayback và các loại khác. Chỉ định sai loại sẽ gây ra ngoại lệ khi khởi động. Thực hành này làm cho Background Service minh bạch hơn cho cả người dùng và hệ thống.

Ví dụ đăng ký Service trong AndroidManifest

Đăng ký Service đúng cách trong tệp kê khai bao gồm thuộc tính exported (khả năng truy cập cho ứng dụng bên ngoài), foregroundServiceType (loại dịch vụ nền trên Android 12+) và quyền. Đối với Bound Service, bạn cũng cần khai báo android:permission="android.permission.BIND_JOB_SERVICE" cho JobIntentService. Không có đăng ký trong tệp kê khai, mọi lệnh gọi startService hoặc bindService sẽ gây ra ngoại lệ, vì vậy kiểm tra tệp kê khai là bước đầu tiên khi chẩn đoán sự cố liên quan đến Service.

Câu hỏi thường gặp

Service chạy trên luồng nào theo mặc định?

Service chạy trên luồng chính (UI Thread) của ứng dụng. Mọi thao tác chặn bên trong onStartCommand hoặc onHandleIntent phải được đưa vào một luồng riêng hoặc coroutine, nếu không hệ thống sẽ gửi ANR sau 5 giây.

IntentService khác Service thông thường như thế nào?

IntentService là một lớp con của Service tự động tạo một luồng công việc và xử lý các lệnh tuần tự. Sau khi hoàn thành tác vụ cuối cùng, IntentService tự dừng. Từ Android 8, IntentService được coi là lỗi thời để chuyển sang JobIntentService hoặc WorkManager.

Có thể khởi động Service khi ứng dụng ở nền trên Android 12 không?

Khởi động Started Service từ nền trên Android 12 bị cấm. Ngoại lệ là Foreground Service với foregroundServiceType được khai báo trong tệp kê khai và thông báo hợp lệ. Việc khởi động ngắn sau khi nhận tin nhắn FCM ưu tiên cao cũng được cho phép.

Làm thế nào để truyền dữ liệu từ Service sang Activity?

Có ba phương pháp: BroadcastReceiver với broadcast cục bộ, cơ chế Messenger qua Handler, và LiveData/Flow trong kiến trúc MVVM với ViewModel dùng chung. Đối với Bound Service, IBinder được sử dụng với lời gọi phương thức trực tiếp.

Điều gì xảy ra khi ứng dụng khởi động lại nếu Service đang chạy?

Nếu Service được khởi động với cờ START_STICKY, hệ thống sẽ khởi động lại nó sau khi tiến trình bị tiêu diệt vì thiếu bộ nhớ. Cờ START_NOT_STICKY có nghĩa là hệ thống sẽ không khởi động lại dịch vụ. START_REDELIVER_INTENT tương tự START_STICKY nhưng gửi Intent cuối cùng.

Tổng kết

  • Background Service là thành phần Android cho thao tác nền không UI, chạy trên luồng chính.
  • Ba loại — Started, Bound và Foreground — bao phủ các kịch bản khác nhau, từ tác vụ một lần đến công việc liên tục có thông báo.
  • Vòng đời bao gồm onCreate, onStartCommand, onBind và onDestroy — cần giải phóng tài nguyên trong onDestroy.
  • Foreground Service là loại duy nhất hoạt động đáng tin cậy trên Android 8+ mà không bị hệ thống tiêu diệt.
  • WorkManager và JobScheduler được ưu tiên cho các tác vụ nền trì hoãn và được đảm bảo.
  • Không sử dụng Service cho các tác vụ yêu cầu thời gian chính xác — hãy dùng AlarmManager.
  • Luôn đăng ký Service trong AndroidManifest.xml và chỉ định android:foregroundServiceType trên Android 12+.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm