Làm theo các phương pháp hay nhất về khoá chế độ thức
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Việc sử dụng khoá chế độ thức có thể làm giảm hiệu suất của thiết bị. Nếu cần sử dụng khoá đánh thức, bạn phải thực hiện đúng cách. Tài liệu này đề cập đến một số phương pháp hay nhất có thể giúp bạn tránh những cạm bẫy phổ biến về khoá đánh thức.
Đặt tên đúng cho khoá chế độ thức
Bạn nên đưa tên gói, lớp hoặc phương thức vào thẻ khoá chế độ thức. Nhờ đó, nếu xảy ra lỗi, bạn sẽ dễ dàng tìm thấy vị trí trong mã nguồn nơi khoá đánh thức được tạo. Dưới đây là một số mẹo bổ sung:
Bỏ mọi thông tin nhận dạng cá nhân (PII) trong tên, chẳng hạn như địa chỉ email. Nếu phát hiện thấy thông tin nhận dạng cá nhân trong thẻ khoá chế độ thức, thiết bị sẽ ghi nhật ký _UNKNOWN thay vì thẻ mà bạn đã chỉ định.
Đừng dùng tên lớp hoặc phương thức thông qua mã, chẳng hạn như gọi getName(). Nếu bạn cố gắng lấy tên theo phương thức lập trình, tên đó có thể bị các công cụ như Proguard làm rối mã nguồn. Thay vào đó, hãy dùng một chuỗi được mã hoá cứng.
Đừng thêm bộ đếm hoặc giá trị nhận dạng duy nhất vào thẻ khoá chế độ thức. Mã tạo khoá đánh thức phải sử dụng cùng một thẻ mỗi khi chạy.
Phương pháp này cho phép hệ thống tổng hợp mức sử dụng khoá đánh thức của từng phương thức.
Đảm bảo ứng dụng của bạn hiển thị ở nền trước
Khi khoá chế độ thức đang hoạt động, thiết bị sẽ tiêu thụ điện. Người dùng thiết bị phải biết rằng điều này đang xảy ra. Vì lý do này, nếu đang dùng khoá chế độ thức, bạn nên hiển thị cho người dùng một số thông báo.
Trên thực tế, điều này có nghĩa là bạn nên lấy và giữ wakelock trong một dịch vụ trên nền trước. Các dịch vụ trên nền trước bắt buộc phải hiển thị một thông báo.
Nếu dịch vụ trên nền trước không phải là lựa chọn phù hợp cho ứng dụng của bạn, thì có lẽ bạn cũng không nên sử dụng khoá đánh thức. Hãy xem tài liệu Chọn API phù hợp để giữ cho thiết bị luôn ở trạng thái hoạt động để biết những cách khác để thực hiện công việc trong khi ứng dụng của bạn không ở nền trước.
Giữ cho logic đơn giản
Hãy đảm bảo các logic thu nạp và hủy bỏ khóa chế độ thức đơn giản nhất có thể. Khi logic khoá chế độ thức liên kết với các máy có trạng thái phức tạp, thời gian chờ, nhóm thực thi hoặc sự kiện gọi lại, thì bất kỳ lỗi nhỏ nào trong logic đó cũng có thể khiến khoá chế độ thức bị giữ lâu hơn dự kiến. Những lỗi này rất khó để chẩn đoán và gỡ lỗi.
Kiểm tra để đảm bảo khoá chế độ thức luôn được giải phóng
Nếu sử dụng khoá chế độ thức, bạn phải đảm bảo rằng mọi khoá chế độ thức mà bạn nhận được đều được huỷ bỏ đúng cách. Việc này không phải lúc nào cũng dễ dàng như bạn tưởng. Ví dụ: mã sau đây có vấn đề:
Kotlin
@Throws(MyException::class)fundoSomethingAndRelease(){wakeLock.apply{acquire()doTheWork()// can potentially throw MyExceptionrelease()// does not run if an exception is thrown}}
Java
voiddoSomethingAndRelease()throwsMyException{wakeLock.acquire();doTheWork();// can potentially throw MyExceptionwakeLock.release();// does not run if an exception is thrown}
Vấn đề ở đây là phương thức doTheWork() có thể gửi ngoại lệ MyException. Nếu có, phương thức doSomethingAndRelease() sẽ truyền ngoại lệ ra ngoài và không bao giờ đạt đến lệnh gọi release(). Kết quả là khoá đánh thức được thu nạp nhưng không được giải phóng, điều này rất tệ.
Trong mã đã sửa, doSomethingAndRelease() đảm bảo giải phóng khoá đánh thức ngay cả khi một ngoại lệ được trả về:
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-08-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-08-27 UTC."],[],[],null,["Using a wake lock can impair device performance. If you need to use a wake\nlock, it's important to do it properly. This document covers some best practices\nthat can help you avoid common wake lock pitfalls.\n| **Note:** Creating and holding wake locks can have a dramatic impact on the device's battery life. You shouldn't use wake locks if there are any suitable alternatives. For other options, see the [Keep the device awake](/develop/background-work/background-tasks/awake) documentation. If you do need to use a wake lock, make sure to hold it for as short a time as possible.\n\nName the wake lock properly\n\nWe recommend including your package, class, or method name in the wakelock\ntag. That way, if an error occurs, it's easier to find the location in your\nsource code where the wake lock was created. Here are some additional tips:\n\n- Leave out any personally identifying information (PII) in the name, such as an email address. If the device detects PII in the wake lock tag, it logs `_UNKNOWN` instead of the tag you specified.\n- Don't get the class or method name programmatically, for example by calling `getName()`. If you try to get the name programmatically, it might get obfuscated by tools like Proguard. Instead use a hard-coded string.\n- Don't add a counter or unique identifiers to wake lock tags. The code that creates a wake lock should use the same tag every time it runs. This practice enables the system to aggregate each method's wake lock usage.\n\nMake sure your app is visible in the foreground\n\nWhile a wake lock is active, the device is using power. The device's user\nshould be aware that this is going on. For this reason, if you're using a\nwake lock, you should display some notification to the user.\nIn practice, this means you should get and hold the wakelock in a\n[foreground service](/develop/background-work/services/fgs). Foreground services are required to display\na notification.\n\nIf a foreground service isn't the right choice for your app,\nyou probably shouldn't be using a wake lock, either. See the\n[Choose the right API to keep the device awake](/develop/background-work/background-tasks/awake)\ndocumentation for other ways to do work while your app isn't in the foreground.\n\nKeep the logic simple\n\nMake sure the logic for acquiring and releasing wake locks is as simple as\npossible. When your wake lock logic is tied to complex state machines, timeouts,\nexecutor pools, or callback events, any subtle bug in that logic can cause the\nwake lock to be held longer than expected. These bugs are difficult to diagnose\nand debug.\n\nCheck that the wake lock is always released\n\nIf you use a wake lock, you must make sure that every wake lock you acquire\nis properly released. This isn't always as easy as it sounds. For example,\nthe following code has a problem: \n\nKotlin \n\n @Throws(MyException::class)\n fun doSomethingAndRelease() {\n wakeLock.apply {\n acquire()\n doTheWork() // can potentially throw MyException\n release() // does not run if an exception is thrown\n }\n }\n\nJava \n\n void doSomethingAndRelease() throws MyException {\n wakeLock.acquire();\n doTheWork(); // can potentially throw MyException\n wakeLock.release(); // does not run if an exception is thrown\n }\n\nThe problem here is that the method `doTheWork()` can throw the exception\n`MyException`. If it does, the `doSomethingAndRelease()` method propagates\nthe exception outward, and it never reaches the `release()` call. The result\nis that the wake lock is acquired but not released, which is very bad.\n\nIn the corrected code, `doSomethingAndRelease()` makes sure to release the\nwake lock even if an exception is thrown: \n\nKotlin \n\n @Throws(MyException::class)\n fun doSomethingAndRelease() {\n wakeLock.apply {\n try {\n acquire()\n doTheWork()\n } finally {\n release()\n }\n }\n }\n\nJava \n\n void doSomethingAndRelease() throws MyException {\n try {\n wakeLock.acquire();\n doTheWork();\n } finally {\n wakeLock.release();\n }\n }"]]