보관 규칙에 대한 정보

기본 설정으로 앱 최적화를 사용 설정하면 R8은 성능 이점을 극대화하기 위해 광범위한 최적화를 실행합니다. R8은 클래스, 필드, 메서드의 이름 바꾸기, 이동, 삭제를 비롯해 코드에 상당한 수정사항을 적용합니다. 이러한 수정으로 인해 오류가 발생하는 경우 유지 규칙에서 선언하여 R8이 수정해서는 안 되는 코드 부분을 지정해야 합니다.

보관 규칙이 필요한 일반적인 시나리오

R8은 코드에서 모든 직접 호출을 식별하고 보존합니다. 하지만 R8은 간접적인 코드 사용을 확인할 수 없으므로 앱에 필요한 코드를 삭제하여 비정상 종료가 발생할 수 있습니다. keep 규칙을 사용하여 R8이 간접적으로 사용되는 코드를 유지하도록 합니다. 보관 규칙이 필요한 몇 가지 일반적인 상황은 다음과 같습니다.

  • 리플렉션으로 액세스하는 코드: R8은 클래스, 필드 또는 메서드가 리플렉션으로 액세스되는 시점을 식별할 수 없습니다. 예를 들어 R8은 Class.getDeclaredMethod()를 사용하여 이름으로 조회된 메서드나 Class.getAnnotation()로 가져온 주석을 식별할 수 없습니다. 이러한 경우 R8은 이러한 메서드와 주석의 이름을 바꾸거나 완전히 삭제할 수 있으므로 런타임에 ClassNotFoundException 또는 NoSuchMethodException가 발생합니다.
  • Java 네이티브 인터페이스 (JNI)에서 호출된 코드: 네이티브 (C 또는 C++) 코드가 Java 또는 Kotlin 메서드를 호출하거나 Java 또는 Kotlin 코드가 JNI를 사용하여 C++ 코드를 호출하면 호출은 메서드 이름의 동적 문자열 조회를 기반으로 합니다. R8은 동적 문자열 기반 메서드 호출을 확인할 수 없으므로 최적화로 인해 코드가 손상될 수 있습니다.

보관 규칙이 필요한 시나리오를 모두 나열한 것은 아니지만, 이러한 시나리오에는 보관 규칙이 필요할 수 있는 대부분의 경우가 포함됩니다.

앱에 keep 규칙을 추가하는 방법

유지 규칙 구성은 사용하는 AGP 버전에 따라 다릅니다.

일반적으로 대규모 앱에는 여러 라이브러리 모듈에 코드가 있습니다. 이 경우 특정 라이브러리 모듈 내에서 적용되는 코드와 함께 유지 규칙을 배치하는 것이 더 나은 경우가 많습니다. 라이브러리의 유지 규칙을 유지하는 데 있어 중요한 차이점은 라이브러리 모듈의 build.gradle.kts (또는 build.gradle) 파일 내에서 이러한 규칙을 선언하는 방식에 있습니다. 자세한 내용은 라이브러리 작성자를 위한 최적화를 참고하세요.

AGP 버전 9.3 이상

src/<variant>/keepRules 디렉터리에서 .keep 접미사가 있는 파일에 규칙을 추가합니다. 예를 들면 src/main/keepRules/custom-rules.keep입니다. AGP 9.3 이상의 업데이트된 DSL을 사용하면 코드와 리소스 최적화가 모두 사용 설정되며 기본 Android 유지 규칙 파일(proguard-android-optimize.txt)이 명시적으로 생략되지 않는 한 기본적으로 포함되므로 명시적으로 정의할 필요가 없습니다.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

기본 Android 플랫폼 유지 규칙 생략 (고급)

AGP는 기본 Android 플랫폼 규칙 집합을 제공합니다. 프로젝트 구성에서 이러한 규칙을 생략하고 모든 보관 규칙을 직접 관리하려면 optimization.keepRules.includeDefaultfalse로 설정하세요.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

AGP 버전이 9.3보다 낮은 경우의 기존 DSL

앱 모듈의 루트 디렉터리에 있는 proguard-rules.pro 파일에 규칙을 추가합니다. 파일이 이미 있을 수도 있지만 없는 경우 파일을 만듭니다. 파일의 규칙을 적용하려면 모듈 수준 build.gradle.kts (또는 build.gradle) 파일에서 파일을 선언해야 합니다.

기본적으로 빌드 파일에는 proguard-android-optimize.txt 파일도 포함됩니다. 이 파일에는 대부분의 Android 프로젝트에 필요한 규칙이 포함되어 있으므로 빌드 파일에 그대로 두어야 합니다. 이 파일은 proguard-common.txt 파일을 기반으로 하며 콘텐츠를 공유합니다.

기존 DSL (Kotlin)

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),
                ...
            )
        }
    }
}

기존 DSL (Groovy)

android {
    buildTypes {
        release {
            minifyEnabled = true
            shrinkResources = true

            // Default file with default optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
            ...
        }
    }
}

보관 규칙 추가

유지 규칙을 추가할 때 전역 옵션을 포함할 수 있으며 자체 유지 규칙을 정의할 수도 있습니다.

  • 전역 옵션: 전역 옵션은 R8이 전체 코드베이스에서 작동하는 방식에 영향을 미치는 일반적인 지시어입니다. 자세한 내용은 전역 옵션을 참고하세요.

  • 유지 규칙: 유지 규칙은 앱을 실수로 중단하지 않고 코드 최적화를 극대화할 수 있도록 신중하게 설계해야 합니다. 유지 규칙을 작성하는 방법을 알아보려면 유지 규칙 추가를 참고하세요.

라이브러리 작성자를 위한 규칙 유지

보관 규칙의 전역 옵션과 구문을 알아본 후 자세한 내용은 라이브러리 작성자를 위한 최적화를 참고하세요.