백그라운드 작업에 관한 시스템 제한사항

백그라운드 프로세스는 메모리와 배터리를 많이 사용할 수 있습니다. 예를 들어 암시적 브로드캐스트는 프로세스가 많은 작업을 하지는 않더라도 수신 대기하도록 등록된 많은 백그라운드 프로세스를 시작할 수 있습니다. 이렇게 되면 기기 성능과 사용자 환경에 모두 상당한 영향을 미치게 됩니다.

시스템 제한사항을 방지하려면 백그라운드 작업에 적합한 API를 사용해야 합니다. 백그라운드 작업 개요 문서를 통해 필요에 맞는 API를 선택할 수 있습니다.

사용자 시작 제한사항

앱이 Android vitals에 설명된 잘못된 동작을 보이면 시스템은 사용자에게 시스템 리소스에 대한 앱의 액세스를 제한하라는 메시지를 표시합니다.

시스템에서 앱이 과도한 리소스를 사용하는 것을 알면 사용자에게 알리고 앱의 작업을 제한하는 옵션을 사용자에게 제공합니다. 알림을 트리거할 수 있는 동작은 다음과 같습니다.

  1. 과도한 wake lock: 화면이 꺼져 있을 때 한 시간 동안 유지되는 한 번의 부분적 wake lock
  2. 과도한 백그라운드 서비스: 앱이 API 수준 26 미만을 타겟팅하고 과도한 백그라운드 서비스가 있는 경우

적용되는 정확한 제한사항은 기기 제조업체에서 결정합니다. 예를 들어 AOSP 빌드에서는 앱이 포그라운드에 있을 때를 제외하고 제한된 앱은 작업을 실행하거나 알람을 트리거하거나 네트워크를 사용할 수 없습니다.

네트워크 활동 브로드캐스트 수신에 관한 제한사항

앱은 매니페스트에서 CONNECTIVITY_ACTION 브로드캐스트를 수신하도록 등록한 경우 해당 브로드캐스트를 수신하지 않고, 이 브로드캐스트에 종속되는 프로세스가 시작되지 않습니다. 이렇게 되면 기기가 무제한 네트워크에 연결될 때 네트워크 변경을 수신 대기하거나 대량 네트워크 활동을 실행하려는 앱에 문제가 생길 수 있습니다. Android 프레임워크에는 이러한 제한사항을 해결하기 위한 여러 솔루션이 있습니다. 앱에서 달성하고자 하는 것에 따라 이 중 적절한 솔루션을 선택해야 합니다.

무제한 연결에서 작업 예약

WorkRequest를 빌드할 때 NetworkType.UNMETERED Constraint를 추가합니다.

fun scheduleWork(context: Context) {
    val workManager = WorkManager.getInstance(context)
    val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
       .setConstraints(
           Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .build()
           )
       .build()

    workManager.enqueue(workRequest)
}

작업의 조건이 충족되면, 앱은 지정된 Worker 클래스에서 doWork() 메서드를 실행하기 위한 콜백을 수신합니다.

앱이 실행되는 동안 네트워크 연결 모니터링

실행 중인 앱은 CONNECTIVITY_CHANGE을(를) 사용하여 등록된 BroadcastReceiver를 계속 수신 대기할 수 있습니다. 그러나 ConnectivityManager API 는 지정된 네트워크 조건이 충족될 때만 콜백을 요청할 수 있는 더 강력한 메서드를 제공합니다.

NetworkRequest 객체는 의 관점에서 네트워크 콜백의 매개변수를 정의합니다.NetworkCapabilities NetworkRequest.Builder 클래스로 NetworkRequest 객체를 만듭니다. registerNetworkCallback 그런 다음 NetworkRequest 객체를 시스템에 전달합니다. 네트워크 조건이 충족되면 앱은 onAvailable() 클래스에 정의된 ConnectivityManager.NetworkCallback 메서드를 실행하기 위한 콜백을 수신합니다.

앱은 앱이 종료되거나 unregisterNetworkCallback()을 호출할 때까지 콜백을 계속 수신합니다.

이미지 및 동영상 브로드캐스트 수신에 관한 제한사항

앱은 ACTION_NEW_PICTURE 또는 ACTION_NEW_VIDEO 브로드캐스트를 송수신할 수 없습니다. 이 제한사항은 여러 앱에서 새로운 이미지나 동영상을 처리하기 위해 절전 모드를 해제해야 할 때 성능과 사용자 환경에 미치는 영향을 완화하는 데 도움이 됩니다.

어떤 콘텐츠 권한이 작업을 트리거했는지 확인

WorkerParameters 를 사용하면 앱에서 어떤 콘텐츠 권한과 URI가 작업을 트리거했는지에 관한 유용한 정보를 수신할 수 있습니다.

List<Uri> getTriggeredContentUris()

작업을 트리거한 URI 목록을 반환합니다. 작업을 트리거한 URI가 없거나 (예: 작업이 기한 또는 기타 이유로 인해 트리거된 경우) 변경된 URI 수가 50보다 크면 이 값은 비어 있습니다.

List<String> getTriggeredContentAuthorities()

작업을 트리거한 콘텐츠 권한의 문자열 목록을 반환합니다. 반환된 목록이 비어 있지 않으면 getTriggeredContentUris()를 사용하여 변경된 URI의 세부정보를 검색합니다.

다음 샘플 코드는 CoroutineWorker.doWork() 메서드 를 재정의하고 작업을 트리거한 콘텐츠 권한과 URI를 기록합니다.

class MyWorker(
    appContext: Context,
    params: WorkerParameters
): CoroutineWorker(appContext, params)
    override suspend fun doWork(): Result {
        StringBuilder().apply {
            append("Media content has changed:\n")
            params.triggeredContentAuthorities
                .takeIf { it.isNotEmpty() }
                ?.let { authorities ->
                    append("Authorities: ${authorities.joinToString(", ")}\n")
                    append(params.triggeredContentUris.joinToString("\n"))
                } ?: append("(No content)")
            Log.i(TAG, toString())
        }
        return Result.success()
    }
}

시스템 제한사항에서 앱 테스트

메모리가 부족한 기기나 조건에서 실행되도록 앱을 최적화하면 성능과 사용자 환경을 개선할 수 있습니다. 백그라운드 서비스 및 매니페스트에 등록된 암시적 브로드캐스트 수신기의 종속 항목을 삭제하면 앱이 이러한 기기에서 더 잘 실행될 수 있습니다. 이러한 백그라운드 프로세스를 완전히 사용하지 않고 앱이 실행되도록 최적화하는 것이 좋습니다.

일부 추가 Android 디버그 브리지 (ADB) 명령어를 사용하면 이러한 백그라운드 프로세스가 사용 중지된 상태로 앱 동작을 테스트할 수 있습니다.

  • 암시적 브로드캐스트 및 백그라운드 서비스를 사용할 수 없는 조건을 시뮬레이션하려면 다음 명령어를 입력합니다.

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore

  • 암시적 브로드캐스트 및 백그라운드 서비스를 다시 사용 설정하려면 다음 명령어를 입력합니다.

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow

앱의 추가 최적화

백그라운드 작업의 동작을 최적화하는 다른 좋은 방법은 작업 예약 API의 배터리 사용 최적화 문서를 참고하세요.