Tải dữ liệu, đồng bộ hóa nội dung, gửi phân tích — nhiều tác vụ không cần sự tham gia tích cực của người dùng. Tuy nhiên, các thiết bị di động hạn chế công việc nền để tiết kiệm pin và duy trì hiệu suất. Tác vụ nền (background tasks) là các cơ chế cho phép ứng dụng thực thi mã khi người dùng không nhìn thấy nó. Trong bài viết này, chúng ta sẽ tìm hiểu về WorkManager, BGTaskScheduler, Foreground Service và các đặc điểm của Doze Mode. Xem chi tiết tại tài liệu chính thức của WorkManager.
Những điểm chính
Tác vụ nền là bất kỳ mã nào được thực thi khi ứng dụng không ở tiền cảnh (màn hình hoạt động). Điều này có thể bao gồm: đồng bộ hóa dữ liệu định kỳ với máy chủ, tải xuống tệp lớn, xử lý thông báo push, theo dõi vị trí địa lý, cập nhật widget. Mỗi nền tảng có các hạn chế riêng về công việc nền: iOS nghiêm ngặt hơn (10–30 phút thời gian nền), Android thoải mái hơn nhưng đã thắt chặt quy tắc từ phiên bản 9.
Kiến trúc của tác vụ nền được xây dựng trên ba cấp độ: (1) tác vụ tức thời — thực thi ngay lập tức (Foreground Service); (2) tác vụ trì hoãn — thực thi trong điều kiện phù hợp (WorkManager, BGTaskScheduler); (3) tác vụ định kỳ — lặp lại theo khoảng thời gian đã đặt. Chọn đúng cấp độ quyết định liệu tác vụ có được hoàn thành đúng hạn hay không và liệu nó có dẫn đến việc bị từ chối trên cửa hàng ứng dụng hay không.
Trên cả hai nền tảng, Google/Apple khuyến nghị mạnh mẽ sử dụng API khai báo thay vì quản lý trực tiếp các luồng trong nền. WorkManager trên Android và BGTaskScheduler trên iOS cho phép hệ thống phân phối tối ưu công việc nền giữa các ứng dụng, nhóm các tác vụ để tiết kiệm năng lượng. Tại IT Sectr, chúng tôi luôn bắt đầu thiết kế kiến trúc nền bằng cách phân tích các yêu cầu về tần suất và mức độ khẩn cấp của các bản cập nhật.
iOS cung cấp một số cơ chế cho công việc nền. Background Fetch — cập nhật nội dung định kỳ với khoảng thời gian do hệ thống xác định (không phải nhà phát triển). Ứng dụng nhận được khoảng ~30 giây để tải dữ liệu mới. Background Fetch được bật qua Capabilities → Background Modes → Background Fetch và được triển khai trong AppDelegate: application(_:performFetchWithCompletionHandler:).
BGTaskScheduler là API hiện đại cho iOS 13+, thay thế Background Fetch. Nhà phát triển đăng ký một tác vụ với định danh, và hệ thống chạy nó khi điều kiện phù hợp. BGAppRefreshTask — cho các cập nhật nội dung ngắn; BGProcessingTask — cho các tác vụ dài (dọn bộ nhớ đệm, đồng bộ cơ sở dữ liệu). Các tác vụ được đăng ký khi khởi động ứng dụng, và hệ thống lên lịch thực thi chúng dựa trên trạng thái pin, mạng và hoạt động của người dùng.
Background Modes — danh sách các chế độ cho phép công việc nền cho các kịch bản cụ thể: Audio (phát lại nền), Location (GPS), VoIP (cuộc gọi qua PushKit), BLE (kết nối thiết bị Bluetooth), Processing (tác vụ dài qua BGTaskScheduler). Mỗi chế độ cần được giải trình trong quá trình đánh giá App Store. Sử dụng chế độ mà không có nhu cầu thực sự là một nguyên nhân phổ biến khiến ứng dụng bị từ chối.
Significant Location Change — cơ chế cho các ứng dụng không cần định vị liên tục nhưng cần biết về sự di chuyển đáng kể của người dùng (hơn 500 mét). Hệ thống đánh thức ứng dụng khi tháp di động thay đổi. Cơ chế này tiết kiệm pin đáng kể so với GPS liên tục.
Android cung cấp bộ API phong phú nhất cho các tác vụ nền, nhưng kể từ phiên bản 8.0 (API 26), các quy tắc đã trở nên nghiêm ngặt hơn. WorkManager là giải pháp được Google khuyến nghị cho tất cả các loại tác vụ nền. WorkManager đảm bảo thực thi tác vụ ngay cả sau khi khởi động lại thiết bị (qua BootReceiver) và hỗ trợ chuỗi tác vụ, LiveData/Flow có thể quan sát và tương thích ngược đến API 14.
WorkManager sử dụng Worker — một lớp cơ sở với phương thức doWork(). Constraints xác định các điều kiện thực thi: NetworkType.CONNECTED, BatteryNotLow, StorageNotLow. PeriodicWorkRequest — cho các tác vụ định kỳ với khoảng thời gian tối thiểu 15 phút. WorkManager tự động thích ứng với Doze Mode và App Standby, nhóm các tác vụ vào các cửa sổ bảo trì. Ví dụ về một Worker đơn giản:
class SyncWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
val repository =
Injection.provideRepository(applicationContext)
repository.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
// Запланировать задачу
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(constraints)
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
JobScheduler — một API cũ hơn (Android 5+, API 21). Nó lên lịch các tác vụ với các điều kiện được chỉ định (mạng, sạc, không hoạt động). Hạn chế: không hỗ trợ khởi động lại thiết bị (cần BootReceiver) và không có trạng thái có thể quan sát. JobScheduler phù hợp cho các tác vụ đơn giản trong các dự án cũ; cho các dự án mới, hãy sử dụng WorkManager.
Foreground Service — một dịch vụ mà người dùng thấy qua thông báo liên tục (ongoing notification). Được sử dụng cho: phát nhạc, theo dõi GPS, tải xuống tệp lớn. Foreground Service có mức ưu tiên cao — hệ thống sẽ không giết nó khi thiếu bộ nhớ. Bắt đầu từ Android 13, cần có quyền FOREGROUND_SERVICE_SPECIAL_USE cho một số loại. Một giải pháp thay thế là WorkManager với ForegroundServiceOption (tác vụ dài).
AlarmManager — cho các tác vụ phải chạy vào thời gian chính xác (báo thức, nhắc nhở). AlarmManager có thể đánh thức thiết bị khỏi Doze Mode (setAlarmClock). Không được khuyến nghị cho đồng bộ hóa thông thường do tiêu thụ điện năng cao. Cho các tác vụ định kỳ, hãy sử dụng WorkManager và AlarmManager chỉ khi thời gian chính xác là quan trọng.
| Kịch bản | iOS | Android |
|---|---|---|
| Cập nhật nội dung định kỳ | BGAppRefreshTask (BGTaskScheduler) | WorkManager (PeriodicWorkRequest) |
| Tác vụ nền dài | BGProcessingTask | WorkManager + ForegroundService |
| Phát âm thanh | Background Audio Mode | Foreground Service |
| Theo dõi GPS | Significant Location Change / Background Location | Foreground Service + FusedLocationProvider |
| VoIP / Cuộc gọi | PushKit + CallKit | ConnectionService + Foreground Service |
| Thời gian chính xác (báo thức) | UNNotificationRequest (calendar) | AlarmManager |
| Xử lý push (nền) | Notification Service Extension | FirebaseMessagingService (onMessageReceived) |
Doze Mode là chế độ tiết kiệm pin trong Android ảnh hưởng đến việc thực thi tác vụ nền. Được giới thiệu trong Android 6.0 (API 23). Khi thiết bị không sạc, màn hình tắt và thiết bị đứng yên, Doze Mode chặn các yêu cầu mạng, trì hoãn JobScheduler và WakeLock. Định kỳ, Doze mở các cửa sổ bảo trì — khoảng thời gian ngắn khi các ứng dụng có thể thực thi các tác vụ đã trì hoãn. Từ Android 7.0 (API 24), Doze kích hoạt khi màn hình tắt, không chỉ khi hoàn toàn đứng yên.
App Standby — chế độ nơi các ứng dụng không được sử dụng được đưa vào trạng thái chờ. Nếu một ứng dụng không có thông báo hoạt động và không được mở trong nhiều ngày, nó được đặt vào Standby Bucket: hoạt động (active), working, frequent, rare. Ứng dụng càng ít được sử dụng, các hạn chế càng nghiêm ngặt: yêu cầu mạng bị trì hoãn, đồng bộ hóa bị chặn, JobScheduler không chạy.
WakeLock — cơ chế giữ cho thiết bị thức (ngăn không cho ngủ). Được sử dụng để hoàn thành các hoạt động quan trọng. WakeLock phải được giải phóng sau khi hoàn thành tác vụ, nếu không pin sẽ cạn kiệt trong vài giờ. WakeLock không hoạt động trong Doze Mode — hệ thống bỏ qua nó. Làm việc với WakeLock trên Android 8+ yêu cầu quyền WAKE_LOCK và quản lý vòng đời phù hợp.
Tại IT Sectr, chúng tôi xem xét Doze Mode và App Standby ở giai đoạn thiết kế. WorkManager tự động xử lý các chế độ này, nhưng đối với Foreground Service cần lên kế hoạch xử lý chính xác các chuyển đổi sang Doze. Khuyến nghị kiểm tra công việc nền trên các thiết bị thực với chế độ tiết kiệm pin được bật và sau thời gian không hoạt động kéo dài.
Khi thiết kế các tác vụ nền, hãy làm theo những mẹo sau. 1. Luôn sử dụng WorkManager cho các dự án Android mới. Nó giải quyết các vấn đề tương thích, Doze Mode và khởi động lại thiết bị. 2. Trên iOS, ưu tiên BGTaskScheduler hơn Background Fetch cho iOS 13+. 3. Chỉ sử dụng Foreground Service khi tác vụ thực sự cần thông báo hiển thị. 4. Không lạm dụng WakeLock — nó làm hao pin và có thể dẫn đến việc bị từ chối ứng dụng. 5. Kiểm tra tác vụ nền trong Doze Mode: adb shell dumpsys deviceidle force-idle. 6. Luôn xác minh hoàn thành tác vụ thông qua ghi nhật ký và phân tích. 7. Nhớ các giới hạn: iOS cho phép ~30 giây cho Background Fetch và ~vài phút cho BGProcessingTask. Android WorkManager không đảm bảo thời gian thực thi chính xác.
Các câu hỏi thường gặp
Background Service chạy mà không có thông báo hiển thị và có thể bị hệ thống giết bất cứ lúc nào. Foreground Service phải hiển thị thông báo liên tục (ongoing notification) và có mức ưu tiên cao hơn. Foreground Service được sử dụng để phát nhạc và theo dõi GPS.
Doze Mode là chế độ tiết kiệm pin của Android vô hiệu hóa truy cập mạng và trì hoãn JobScheduler/WakeLock khi thiết bị không được sử dụng. WorkManager thích ứng với Doze Mode tự động.
Trên iOS, các tác vụ nền được chạy qua Background Fetch (cập nhật định kỳ), BGTaskScheduler (tác vụ trì hoãn) hoặc Background Modes (âm thanh, VoIP, BLE, vị trí). BGTaskScheduler là API hiện đại cho iOS 13+, thay thế Background Fetch.
WorkManager là giải pháp được Google khuyến nghị cho tất cả các tác vụ nền trên Android. JobScheduler là API cũ hơn với khả năng hạn chế. WorkManager hỗ trợ chuỗi tác vụ, LiveData/Flow có thể quan sát và tương thích ngược đến API 14.
App Standby là chế độ Android nơi các ứng dụng không được sử dụng được đưa vào trạng thái chờ: các yêu cầu mạng bị trì hoãn, đồng bộ hóa bị tạm dừng. Nếu một ứng dụng không được sử dụng trong nhiều ngày, Android đặt nó vào Standby Bucket (active, working, frequent, rare).
Tóm tắt
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.