시계 모드 최적화

Wear OS 시계 모드는 지속적으로 실행되므로 전력을 효율적으로 사용해야 합니다.

또한 시계 모드의 성능을 최적화해야 합니다. 서비스는 불필요한 계산을 수행해서는 안 됩니다. 애니메이션이 있는 시계 모드는 알림 및 시스템 표시기를 수용하면서 원활하게 실행되어야 합니다.

기본 최적화

이 섹션에는 효율성 향상을 위한 권장사항이 포함되어 있습니다.

시계 모드의 색상 및 밝기

어두운 색상은 시계 배터리를 보존합니다. 시계 모드의 배터리 사용을 최적화하기 위해 시계 모드 배경을 설정하기 위한 권장사항은 다음과 같습니다.

  • 색상. 가능한 경우 검은색 배경을 사용합니다.
  • 밝기. 시계 모드의 요구사항으로 인해 검은색 배경을 사용할 수 없는 경우 HSV(색조, 채도, 값) 또는 HSB 스케일에서 배경색의 밝기를 25% 이하로 유지해야 합니다. 예를 들어 Color 클래스를 사용하여 배경색을 설정하고 HSV 스케일로 색상을 정의하는 경우 값 설정(즉, 밝기 설정)에 25 이하를 사용합니다.

WatchFaceService.Engine에서 콜백 사용

시계 모드는 활성 상태일 때만 계산을 수행해야 합니다. WatchFaceService.Engine에서 콜백을 사용합니다. 시계 모드가 표시되는지 확인하려면 이 클래스의 다음 메서드를 사용하는 것이 좋습니다.

  • onVisibilityChanged(boolean)
  • isVisible()

또는 같은 클래스(WatchFaceService.Engine)의 다음 메서드를 사용합니다.

  • onCreate()
  • onDestroy()

DataClient 인터페이스에서 등록된 리스너 사용

이벤트를 수신하려면 DataClient.addListener에서 등록된 라이브 리스너를 사용합니다. 예제를 보려면 데이터 항목 동기화를 참조하세요.

이벤트 수신에 WearableListenerService를 사용하지 마세요. 시계 모드 활성 여부와 상관없이 호출되기 때문입니다. 자세한 내용은 BIND_LISTENER 지원 중단을 참조하세요.

시간대 변경, 배터리 이벤트 등의 시스템 이벤트를 가져오기 위해 Android manifest 파일에서 broadcast receiver를 등록하지 마세요. BroadcastReceiver는 시계 모드의 활성 여부와 상관없이 호출되기 때문입니다. 그러나 Context 클래스의 registerReceiver 메서드를 사용하여 receiver를 등록할 수 있습니다.

스마트폰과의 상호작용을 위해 동적 기능 사용

시계 모드가 스마트폰에서 작업을 실행해야 하는 경우, 관련 코드는 시계 모드가 활성 상태일 때만 실행되어야 합니다. 스마트폰의 앱에 해당하는 시계 모드가 활성 상태임을 알리려면 CapabilityClient API를 사용하는 것이 좋습니다.

동적으로 추가되는 기능은 WatchFaceService.EngineonCreate() 메서드에서 정의합니다. onDestroy() 메서드를 사용하여 기능을 삭제합니다.

예를 들어 시계 모드에 표시할 주기적 데이터를 가져오는 앱은 시계 모드에서 광고하는 기능에 관한 리스너를 등록해야 합니다. 업데이트된 데이터를 가져오고 가까이 있을 때 시계 모드에 푸시할 수 있도록 하려면 알람을 추가합니다. 시계 모드가 선택되지 않았거나 시계가 가까이 있지 않거나, 꺼져 있거나, 업데이트를 받을 수 없는 경우 주기적 알람을 삭제합니다.

전력 소모 모니터링

Wear OS 호환 앱을 사용하면 개발자와 사용자는 웨어러블 기기의 서로 다른 프로세스에서 배터리가 얼마나 소모되는지를 파악할 수 있습니다(설정 > 배터리 확인 아래).

Android 5.0에 도입된 기능 중 배터리 수명 연장에 도움이 되는 기능에 관한 자세한 내용은 프로젝트 Volta를 참조하세요.

암호화 인식 시계 모드 등록

Android 7.0 이상은 파일 기반 암호화를 지원하며, 부팅 시 사용자가 복호화 비밀번호를 제공하기 전에 암호화 인식 애플리케이션을 실행할 수 있습니다. 이렇게 하면 부팅 애니메이션에서 시계 모드로 전환하는 데 걸리는 시간을 최대 30초 단축할 수 있습니다.

부팅 속도를 높이려면 시계 모드 manifest에 android:directBootAware="true"를 추가합니다.

참고: 사용자 인증 정보로 암호화된 저장소를 사용하지 않는 시계 모드에서 이 기능을 사용하세요.

애니메이션 권장사항

이 섹션의 권장사항은 애니메이션의 전력 소모를 줄이는 데 도움이 됩니다.

애니메이션의 프레임 속도 줄이기

애니메이션은 종종 계산 비용이 많이 들고 전력 소모가 큽니다. 대부분의 애니메이션은 초당 30프레임에서 자연스럽게 실행되므로 더 빠른 프레임 속도로 애니메이션을 실행하지 않아야 합니다. draw() 메서드의 끝에서 invalidate()가 사용될 때 invalidate() 메서드를 호출하기 전에 지연을 추가하여 프레임 속도를 제어할 수 있습니다. 이 단계의 구현 방법은 시계 모드 그리기를 참조하세요.

애니메이션 간에 CPU 휴지

애니메이션 실행 및 시계 모드 콘텐츠의 작은 변경 시 CPU가 휴지 상태에서 깨어납니다. 시계 모드에서는 애니메이션 사이에 CPU 휴지를 허용해야 합니다. 예를 들어, 대화형 모드에서 매초 애니메이션의 짧은 버스트를 사용하고 다음 초까지 CPU 휴지를 허용할 수 있습니다. 짧게라도 CPU 휴지를 종종 허용하면 전력 소모를 크게 줄일 수 있습니다.

배터리 수명을 최대화하려면 애니메이션 사용을 줄이세요. 깜박이는 콜론조차도 깜박일 때마다 CPU를 깨우고 배터리 수명을 줄입니다.

비트맵 애셋의 크기 줄이기

다수의 시계 모드는 시간 경과에 따라 움직이는 시곗바늘 및 기타 디자인 요소와 같이 배경 이미지와 배경 이미지 위에서 변형되고 중첩되는 기타 그래픽 애셋으로 구성됩니다. 시계 모드 그리기에 설명된 것처럼 일반적으로 이러한 그래픽 요소는 시스템에서 시계 모드를 다시 그릴 때마다 Engine.onDraw() 메서드 내에서 회전(때로는 크기 조정)됩니다.

그래픽 애셋이 클수록 변형을 위한 계산 비용이 더 많이 듭니다. Engine.onDraw() 메서드에서 큰 그래픽 애셋을 변형하면 시스템이 애니메이션을 실행할 수 있는 프레임 속도가 크게 줄어듭니다.

그림 1. 시곗바늘을 잘라 여분의 픽셀 삭제 가능

시계 모드의 성능을 높이려면 다음과 같이 하세요.

  • 필요한 것보다 큰 그래픽 요소를 사용하지 않습니다.
  • 가장자리 주변의 투명 픽셀을 삭제합니다.

그림 1의 왼쪽에 있는 예제 시곗바늘은 97%까지 크기를 줄일 수 있습니다.

이 섹션에서 설명한 대로 비트맵 애셋의 크기를 줄이면 애니메이션 성능이 향상될 뿐만 아니라 전력이 절약됩니다.

비트맵 애셋 결합

함께 자주 그리는 비트맵이 있는 경우 동일한 그래픽 애셋으로 결합하는 것을 고려해 볼 수 있습니다. 대화형 모드에서 배경 이미지를 눈금과 결합하면 시스템이 시계 모드를 다시 그릴 때마다 두 개의 전체 화면 비트맵을 그리지 않아도 됩니다.

크기 조정된 비트맵을 그릴 때 앤티앨리어싱 사용 중지

Canvas.drawBitmap() 메서드를 사용하여 Canvas 객체에서 크기 조정된 비트맵을 그릴 때 Paint 인스턴스를 제공하여 여러 옵션을 구성할 수 있습니다. 성능을 높이려면 setAntiAlias() 메서드를 사용하여 앤티앨리어싱을 사용 중지합니다. 이 옵션은 비트맵에 아무런 영향도 주지 않기 때문입니다.

그림 2. 비트맵 필터링의 사용 중지(왼쪽) 및 사용 설정(오른쪽) 예

비트맵 필터링 사용

다른 요소 위에 그리는 비트맵 애셋의 경우 setFilterBitmap() 메서드를 사용하여 동일한 Paint 인스턴스에서 비트맵 필터링을 사용 설정합니다. 그림 2는 비트맵 필터링을 사용한 경우와 사용하지 않은 경우의 확대된 시곗바늘 모습을 보여줍니다.

참고: 저비트 대기 모드에서 시스템은 비트맵 필터링이 성공적으로 처리되도록 이미지의 색상을 안정적으로 렌더링하지 않습니다. 대기 모드가 활성화되면 비트맵 필터링을 사용 중지하세요.

비용이 많이 드는 작업을 그리기 메서드 외부로 이동

시스템은 시계 모드를 다시 그릴 때마다 Engine.onDraw() 메서드를 호출합니다. 따라서 성능을 높이려면 시계 모드를 반드시 업데이트해야 하는 작업만 이 메서드 내부에 포함해야 합니다.

가능하면 Engine.onDraw() 메서드 내부에서 다음 작업을 실행하지 마세요.

  • 이미지 및 기타 리소스 로드
  • 이미지 크기 조정
  • 객체 할당
  • 결과가 프레임 간에 변경되지 않는 계산 실행

일반적으로 이러한 작업은 Engine.onCreate() 메서드에서 대신 실행할 수 있습니다. 캔버스의 크기를 제공하는 Engine.onSurfaceChanged() 메서드에서 미리 이미지의 크기를 조정할 수 있습니다.

시계 모드의 성능을 분석하려면 CPU 프로파일러를 사용합니다. 특히 Engine.onDraw() 구현의 실행 시간이 호출 전체에서 짧고 일관성이 있어야 합니다. 자세한 내용은 메서드 추적 기록 및 검사를 참조하세요.