WakeLock là một cơ chế Android ngăn thiết bị chuyển sang chế độ ngủ bằng cách giữ CPU hoặc màn hình hoạt động. Các tác vụ nền như tải tệp, phát âm thanh hoặc ghi dữ liệu yêu cầu WakeLock để đảm bảo thực thi không bị gián đoạn. Theo thông số kỹ thuật của Android Developers, 2025, việc sử dụng WakeLock không đúng cách dẫn đến hao pin nhanh và có thể khiến ứng dụng bị chặn trên Google Play.
Những điểm chính
WakeLock là khóa hệ thống ngăn Android đưa thiết bị vào chế độ năng lượng thấp. Thông thường, sau vài giây người dùng không tương tác, Android tắt màn hình và đưa CPU vào trạng thái ngủ sâu (deep sleep), tạm dừng các luồng nền. WakeLock ngăn chặn sự chuyển đổi này bằng cách giữ CPU hoạt động.
Cơ chế WakeLock được quản lý thông qua dịch vụ hệ thống PowerManager, truy cập qua phương thức getSystemService(Context.POWER_SERVICE). Nhà phát triển tạo một đối tượng WakeLock, chỉ định loại khóa và phải giải phóng nó sau khi hoàn thành tác vụ, nếu không pin của thiết bị sẽ cạn kiệt nhanh chóng. Hệ thống không tự động giải phóng WakeLock — đó là trách nhiệm của ứng dụng.
Với mỗi bản phát hành chính của Android, Google thắt chặt kiểm soát đối với WakeLock. Bắt đầu từ Android 9 (API 28), ứng dụng chạy nền không thể có được WakeLock nếu không có lý do chính đáng và hệ thống theo dõi các ứng dụng lạm dụng khóa và có thể giải phóng chúng một cách cưỡng chế. Trong Android 12+, các hạn chế bổ sung đối với quyền truy cập PowerManager cho ứng dụng nền đã được đưa ra.
WakeLock cần thiết trong các tình huống tác vụ không thể bị gián đoạn do thiết bị chuyển sang chế độ ngủ: tải tệp lớn qua kết nối không ổn định, ghi video, thực hiện các phép tính dài mà không có tương tác của người dùng. Nếu không có khóa ngủ, CPU sẽ vào trạng thái ngủ sâu, tất cả các luồng bị đóng băng và tác vụ vẫn chưa hoàn thành.
Tuy nhiên, Google khuyến nghị giảm thiểu việc sử dụng WakeLock. Trong hầu hết các trường hợp, tác vụ tương tự có thể được giải quyết bằng Foreground Service với thông báo, WorkManager hoặc JobScheduler. Các cơ chế này xem xét trạng thái pin và mạng, kéo dài thời lượng pin của thiết bị.
WakeLock hoạt động thông qua dịch vụ hệ thống PowerManager, quản lý trạng thái nguồn của thiết bị. Khi ứng dụng yêu cầu khóa qua powerManager.newWakeLock(), hệ thống tăng mức hoạt động của CPU, ngăn chặn trạng thái ngủ sâu. Sau khi gọi wakeLock.release(), hệ thống trở về chế độ tiết kiệm năng lượng bình thường.
Điều quan trọng là hiểu rằng WakeLock không ngăn chặn tất cả các chế độ tiết kiệm năng lượng. Doze Mode (chế độ ngủ từ Android 6+) có thể bỏ qua WakeLock trong một số giai đoạn — ứng dụng giữ WakeLock sẽ không có quyền truy cập mạng trong các cửa sổ bảo trì Doze. Điều này có nghĩa là ngay cả WakeLock đang hoạt động cũng không đảm bảo các hoạt động mạng trong giai đoạn thứ hai của Doze.
Mỗi WakeLock được liên kết với PowerManager.WakeLock ở phía framework. Hệ thống đếm các khóa đang hoạt động ở cấp tiến trình: nếu một tiến trình giữ nhiều WakeLock, chúng sẽ tích lũy và việc giải phóng chỉ xảy ra sau khi gọi release() cho mỗi khóa. Android cũng hỗ trợ thời gian chờ wake lock — tự động giải phóng sau một khoảng thời gian nhất định. Tuy nhiên, không nên dựa vào thời gian chờ: tác vụ có thể hoàn thành sớm hơn và thời gian giữ thêm sẽ làm giảm tuổi thọ pin.
Khi thiết bị chuyển sang chế độ ngủ (nút nguồn), Android giải phóng cưỡng chế tất cả SCREEN_DIM_WAKE_LOCK và SCREEN_BRIGHT_WAKE_LOCK nhưng giữ lại PARTIAL_WAKE_LOCK. Điều này có nghĩa là khóa màn hình không thể giữ màn hình sáng — chỉ PARTIAL_WAKE_LOCK có thể tiếp tục hoạt động sau khi nhấn nút nguồn.
Android có một số loại WakeLock, mỗi loại điều khiển các thành phần thiết bị cụ thể. Việc chọn loại xác định thành phần phần cứng nào vẫn hoạt động sau khi khóa. Chọn sai loại dẫn đến tiêu thụ điện năng quá mức do giữ các mô-đun không cần thiết hoạt động.
| Loại | CPU | Màn hình | Bàn phím | Khi nào sử dụng |
|---|---|---|---|---|
| PARTIAL_WAKE_LOCK | Bật | Tắt | Tắt | Tải tệp, tính toán |
| SCREEN_DIM_WAKE_LOCK | Bật | Mờ | Tắt | Trình phát video, bài thuyết trình |
| SCREEN_BRIGHT_WAKE_LOCK | Bật | Sáng | Tắt | Trò chơi (không dùng nữa) |
| FULL_WAKE_LOCK | Bật | Sáng | Sáng | Không dùng nữa (deprecated) |
PARTIAL_WAKE_LOCK là loại được sử dụng nhiều nhất và được khuyến nghị. Nó giữ CPU hoạt động nhưng cho phép tắt màn hình và đèn nền bàn phím. Đây là lựa chọn tối ưu cho các tác vụ nền: tải dữ liệu, xử lý hình ảnh, đồng bộ hóa. Màn hình tắt sau thời gian chờ của hệ thống, tiết kiệm pin trong khi thực hiện công việc mà người dùng không nhìn thấy.
SCREEN_DIM_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK và FULL_WAKE_LOCK đã không còn được dùng kể từ Android 7 (API 24). Chúng giữ màn hình sáng, dẫn đến tiêu thụ pin đáng kể. Google khuyến nghị sử dụng FLAG_KEEP_SCREEN_ON qua Activity.getWindow().addFlags() thay thế — cờ này chỉ hoạt động khi Activity đang hoạt động và không yêu cầu quyền WAKE_LOCK, trong khi hệ thống tự động quản lý thời gian giữ màn hình.
WakeLock là một trong những yếu tố tiêu hao pin chính trên Android. Mỗi giây giữ khóa ngủ tiêu thụ thêm năng lượng vì CPU không thể chuyển sang trạng thái C tiết kiệm năng lượng. Nghiên cứu của Google Power Dashboard cho thấy các ứng dụng có WakeLock được giải phóng không đúng cách có thể tăng mức tiêu thụ điện năng của thiết bị lên 30–50% ở chế độ chờ.
Hệ thống theo dõi các ứng dụng lạm dụng WakeLock thông qua thành phần Battery Historian. Nhà phát triển có thể phân tích hồ sơ tiêu thụ điện năng và xác định rò rỉ khóa — các tình huống khi WakeLock được tạo nhưng không được giải phóng. Google Play Console hiển thị thống kê WakeLock cho các ứng dụng đã xuất bản và thời gian giữ cao có thể dẫn đến đánh giá kém.
Doze Mode và App Standby hạn chế thêm hoạt động của WakeLock. Trong giai đoạn Doze đầu tiên (Light Doze), hệ thống cho phép WakeLock trong các cửa sổ bảo trì ngắn. Trong giai đoạn thứ hai (Deep Doze), WakeLock được hợp nhất với các khóa khác và thực thi trong một cửa sổ chung. Nếu ứng dụng giữ WakeLock hơn 10 phút mà không có tương tác của người dùng, hệ thống có thể giải phóng nó một cách cưỡng chế và thêm ứng dụng vào danh sách đen tối ưu hóa pin.
Sử dụng WakeLock đúng cách là sự cân bằng giữa nhu cầu hoàn thành tác vụ và việc chăm sóc pin của thiết bị. Google khuyến nghị tuân theo một số nguyên tắc: luôn giải phóng WakeLock trong khối finally hoặc qua acquire(timeout), sử dụng loại khóa tối thiểu cần thiết và tránh giữ lâu nếu không thực sự cần thiết.
WakeLock nên được giải phóng trong cùng khối mã nơi nó được tạo. Để đảm bảo giải phóng khi có ngoại lệ, sử dụng cấu trúc try-finally hoặc khối use của Kotlin. Trên Android 10+, hệ thống hiển thị cảnh báo trong logcat nếu WakeLock được giữ hơn 60 giây: "WakeLock held for more than 60 seconds" — đây là dấu hiệu của rò rỉ tiềm ẩn.
Phương thức acquire(long timeout) tự động giải phóng WakeLock sau thời gian chỉ định tính bằng mili giây. Đây là biện pháp bảo vệ trong trường hợp mã giải phóng không thực thi do ngoại lệ hoặc lỗi. Khuyến nghị luôn chỉ định thời gian chờ bằng thời gian thực thi tác vụ tối đa dự kiến cộng thêm biên độ 10–20%.
Trước khi gọi release(), cần kiểm tra xem WakeLock có đang được giữ hay không. Gọi lại release() mà không có acquire() trước đó gây ra RuntimeException: WakeLock under-locked. Khuyến nghị lưu trữ cờ trạng thái (isHeld) và kiểm tra wakeLock.isHeld() trước khi giải phóng.
Hãy xem xét việc tạo và giải phóng đúng cách WakeLock trong Kotlin. Ví dụ minh họa tải dữ liệu không đồng bộ với việc giữ PARTIAL_WAKE_LOCK, giải phóng được đảm bảo trong khối try-finally và thời gian chờ được chỉ định như biện pháp bảo vệ chống rò rỉ. Dịch vụ sử dụng CoroutineScope với bộ điều phối IO để thực thi tác vụ nền.
class DownloadService : Service() {
private lateinit var wakeLock: PowerManager.WakeLock
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
override fun onCreate() {
super.onCreate()
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"download:wakelock"
)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
wakeLock.acquire(60000)
scope.launch {
try {
downloadFile()
} finally {
if (wakeLock.isHeld()) {
wakeLock.release()
}
}
}
return START_NOT_STICKY
}
private suspend fun downloadFile() {
// Mô phỏng tải tệp
delay(30000)
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()
if (wakeLock.isHeld()) {
wakeLock.release()
}
}
override fun onBind(intent: Intent): IBinder? = null
}
Để sử dụng WakeLock, cần thêm quyền vào AndroidManifest.xml. Quyền WAKE_LOCK là quyền thông thường — không yêu cầu yêu cầu thời gian chạy từ người dùng và được cấp tự động khi cài đặt ứng dụng. Tuy nhiên, Google Play có thể từ chối xuất bản nếu ứng dụng không có trường hợp sử dụng rõ ràng cho WakeLock.
<uses-permission
android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="android.permission.DEVICE_POWER" />
WakeLock là cơ chế cấp thấp và Google khuyến nghị thay thế nó bằng các API hiện đại hơn bất cứ khi nào có thể. Giải pháp thay thế chính là Foreground Service với thông báo, tự động giữ khóa CPU trong suốt thời gian dịch vụ hoạt động. Hệ thống tự quản lý WakeLock cho Foreground Service, giải phóng nhà phát triển khỏi việc đạt được và giải phóng rõ ràng.
WorkManager là công cụ quan trọng thứ hai cho các tác vụ nền. Nó đảm bảo thực thi tác vụ ngay cả khi thiết bị vào chế độ Doze và sau khi khởi động lại. WorkManager hỗ trợ khóa giữ (hold lock) nội bộ — nhà phát triển không cần làm việc rõ ràng với PowerManager. Tác vụ được thực thi trong cửa sổ bảo trì Doze với quản lý khóa ngủ tự động.
Đối với các tác vụ định kỳ yêu cầu thời gian chính xác, sử dụng AlarmManager với setAndAllowWhileIdle(), có thể đánh thức thiết bị khỏi Doze. Tuy nhiên, AlarmManager chỉ phù hợp cho các thao tác ngắn — nó không được thiết kế cho việc giữ WakeLock lâu dài. Nếu tác vụ mất hơn 10 giây, hãy kết hợp AlarmManager với BroadcastReceiver để khởi động Foreground Service.
Các câu hỏi thường gặp
WakeLock là khóa hệ thống ngăn thiết bị Android chuyển sang chế độ ngủ. Nó giữ CPU hoặc màn hình hoạt động, cho phép các tác vụ nền (tải xuống, tính toán) chạy không bị gián đoạn. Nó được quản lý thông qua dịch vụ hệ thống PowerManager.
Các loại chính là: PARTIAL_WAKE_LOCK (CPU hoạt động, màn hình tắt) — được khuyến nghị; SCREEN_DIM_WAKE_LOCK (CPU + màn hình mờ); SCREEN_BRIGHT_WAKE_LOCK (CPU + màn hình sáng). SCREEN_DIM, SCREEN_BRIGHT và FULL_WAKE_LOCK không còn được dùng và đã được thay thế bằng FLAG_KEEP_SCREEN_ON.
Có, cần khai báo android.permission.WAKE_LOCK trong tệp kê khai. Đây là quyền thông thường được cấp tự động khi cài đặt — không cần yêu cầu trong thời gian chạy. Nếu không có quyền này, lệnh gọi newWakeLock() sẽ trả về null hoặc ném ra SecurityException.
Nếu không gọi release(), thiết bị không thể chuyển sang chế độ ngủ. Pin sẽ cạn kiệt nhanh hơn đáng kể (lên đến 50% tiêu thụ thêm). Hệ thống sẽ ghi lại rò rỉ trong logcat và Battery Historian sẽ hiển thị thời gian giữ WakeLock bất thường, dẫn đến đánh giá kém từ người dùng.
Đối với các tác vụ dài, hãy sử dụng Foreground Service với thông báo — hệ thống tự quản lý WakeLock. Đối với các tác vụ trì hoãn và được đảm bảo, hãy sử dụng WorkManager, hỗ trợ WakeLock nội bộ. Đối với các tác vụ ngắn theo lịch, hãy sử dụng AlarmManager.
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.
Đọc thêm