안드로이드는 디바이스가 사용되지 않을 때 배터리가 소모되지 않도록 절전모드로 전환됩니다. 절전모드로 진입하면 화면도 꺼지고 CPU도 멈추게 됩니다.
만약 내 앱의 Background Process에서 시간이 오래 걸리는 작업을 처리하고 있었는데, 절전모드로 진입하였다면 Process가 Sleep 상태에 빠져 아무 일도 하지 않을 수 있습니다. 이럴 때, WakeLock을 이용하여 문제를 해결할 수 있습니다.
WakeLock은 디바이스가 Sleep 상태에 빠지지 않도록 합니다. 작업을 처리하기 전에 WakeLock을 얻고, 모든 작업이 완료된 뒤에 WakeLock을 시스템에 반환하면 작업이 처리되는 중에 CPU가 멈추지 않게 됩니다.
WakeLock 권한
WakeLock을 사용하려면 AndroidManifest에 다음 권한을 추가해야 합니다.
<uses-permission android:name="android.permission.WAKE_LOCK" />
앱이 설치되는 동시에 권한을 갖는 Install Permission이기 때문에 Manifest에 선언만 하면 됩니다.
WakeLock 예제
다음은 WakeLock을 이용하여 어떤 작업을 처리하는 예제입니다.
// 1. Aquire wakelock
val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock: PowerManager.WakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag")
wakeLock.acquire()
// 2. Perform your tasks
// 3. Release wakelock
wakeLock.release()
- Background Thread에 오래 걸리는 작업을 하기 전에 WakeLock을 획득해야 합니다.
newWakeLock(level, name)
으로 WakeLock을 생성할 수 있으며,acquire()
를 호출하면 WakeLock을 획득하게 됩니다. - 오래 걸리는 작업을 처리하면 됩니다.
- 작업이 모두 완료되었다면
release()
로 WakeLock을 반환해야 합니다. 반환하지 않으면 디바이스는 계속 깨어있는 상태가 되어 배터리가 소모됩니다.
WakeLock Level
newWakeLock()
의 인자로 전달되는 Level은 다음과 같은 것들이 있습니다.
Flag Value | CPU | Screen | Keyboard |
---|---|---|---|
PARTIAL_WAKE_LOCK | On | Off | Off |
SCREEN_DIM_WAKE_LOCK | On | Dim | Off |
SCREEN_BRIGHT_WAKE_LOCK | On | Bright | Off |
FULL_WAKE_LOCK | On | Bright | Bright |
Android Developer의 PowerManager의 설명을 정리하였습니다. Deprecated된 FLAG에 대한 내용은 사이트에서 직접 확인하세요.
- PARTIAL_WAKE_LOCK : screen과 keyboard의 backlight는 꺼지고 CPU는 동작합니다. 사용자가 Power 버튼을 눌러 screen을 꺼도 CPU는 WakeLock이 release될 때까지 동작합니다.
- SCREEN_DIM_WAKE_LOCK : 이 옵션은 Deprecated되었고, 대신
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
를 이용하라고 합니다. - SCREEN_BRIGHT_WAKE_LOCK : 이 옵션은 Deprecated되었고, 대신
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
를 이용하라고 합니다. - FULL_WAKE_LOCK : 이 옵션은 Deprecated되었고, 대신
WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
를 이용하라고 합니다.
WakeLock Timeout
위의 예제에서는 명시적으로 release()
를 호출해야 했습니다. 실수로 release()
를 빼먹으면 디바이스는 항상 켜있게 되고 배터리는 빠르게 소모하게 됩니다.
acquire(timeout)
를 사용하면 인자로 전달된 시간 뒤에 release()
가 호출되어 WakeLock이 자동으로 해제됩니다. 실수로 release()
를 호출하지 않는 경우를 예방할 수 있습니다. (timeout의 시간 단위는 millisecond 입니다.)
그렇기 때문에 Timeout은 작업이 처리되는데 예상되는 시간보다 충분히 많은 시간을 넣어주면 좋습니다. 또한, 작업을 마친 후 명시적으로 WakeLock을 해제하도록 구현해야 배터리를 아낄 수 있습니다.
// 1. Aquire wakelock
val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
val wakeLock: PowerManager.WakeLock =
pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag")
wakeLock.acquire(60 * 1000) // 60 sec
// 2. Perform your tasks
// 3. Release WakeLock
if (wakeLock.isHeld) {
wakeLock.release()
}
acquire(60 * 1000)
으로 60초 뒤에도 WakeLock이 해제되지 않으면 자동으로 해제되도록 Timeout을 설정하였습니다.- 작업을 수행합니다.
- 작업이 완료되었을 때 WakeLock을 해제합니다.
isHeld()
는 WakeLock을 획득하고 있을 때 true를 리턴합니다.
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력