라이브러리 작성자는 앱 개발자가 고품질 최종 사용자 환경을 유지하면서 라이브러리를 앱에 쉽게 통합할 수 있도록 해야 합니다. 라이브러리가 추가 설정 없이 Android 최적화와 호환되는지 확인하거나 라이브러리가 Android에서 사용하기에 적합하지 않을 수 있음을 문서화해야 합니다.
이 문서는 게시된 라이브러리의 개발자를 대상으로 하지만 대규모 모듈식 앱의 내부 라이브러리 모듈 개발자에게도 유용할 수 있습니다.
앱 개발자이고 Android 앱 최적화에 관해 알아보려면 앱 최적화 사용 설정을 참고하세요. 사용하기 적합한 라이브러리에 관해 알아보려면 라이브러리 현명하게 선택하기를 참고하세요.
리플렉션 대신 codegen 사용
가능하면 리플렉션 대신 코드 생성 (codegen)을 사용하세요. 코드 생성과 리플렉션은 모두 프로그래밍할 때 상용구 코드를 피하는 일반적인 접근 방식이지만 코드 생성은 R8과 같은 앱 최적화 도구와 더 호환됩니다.
- codegen을 사용하면 빌드 프로세스 중에 코드가 분석되고 수정됩니다. 컴파일 시간 이후에는 큰 수정이 없으므로 최적화 도구는 궁극적으로 필요한 코드와 안전하게 삭제할 수 있는 코드를 알 수 있습니다.
- 리플렉션을 사용하면 코드가 런타임에 분석되고 조작됩니다. 코드는 실행될 때까지 실제로 완성되지 않으므로 최적화 도구는 안전하게 삭제할 수 있는 코드를 알 수 없습니다. 런타임 중에 리플렉션을 통해 동적으로 사용되는 코드가 삭제되어 사용자에게 앱 비정상 종료가 발생할 수 있습니다.
많은 최신 라이브러리는 리플렉션 대신 codegen을 사용합니다. Room, Dagger2 등에서 사용하는 공통 진입점은 KSP를 참고하세요.
반성이 허용되는 경우
반사를 사용해야 하는 경우 다음 중 하나에만 반사해야 합니다.
- 특정 타겟팅 유형 (특정 인터페이스 구현자 또는 서브클래스)
- 특정 런타임 주석을 사용하는 코드
이러한 방식으로 리플렉션을 사용하면 런타임 비용이 제한되고 타겟팅된 소비자 유지 규칙을 작성할 수 있습니다.
이러한 구체적이고 타겟팅된 리플렉션 형식은 Android 프레임워크 (예: 활동, 뷰, 드로어블 확장)와 AndroidX 라이브러리 (예: WorkManager ListenableWorkers 또는 RoomDatabases 구성)에서 모두 볼 수 있는 패턴입니다. 반면 Gson은 Android 앱에서 사용하기에 적합하지 않습니다의 개방형 반사는 적절하지 않습니다.
소비자 유지 규칙 작성
라이브러리는 앱 유지 규칙과 동일한 형식을 사용하는 '소비자' 유지 규칙을 패키징해야 합니다. 이러한 규칙은 라이브러리 아티팩트 (AAR 또는 JAR)에 번들로 묶이며 라이브러리가 사용될 때 Android 앱 최적화 중에 자동으로 사용됩니다.
AAR 라이브러리
AAR 라이브러리의 소비자 규칙을 추가하려면 Android 라이브러리 모듈의 빌드 스크립트에서 consumerProguardFiles
옵션을 사용합니다. 자세한 내용은 라이브러리 모듈 만들기 가이드를 참고하세요.
Kotlin
android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } ... }
Groovy
android { defaultConfig { consumerProguardFiles 'consumer-proguard-rules.pro' } ... }
JAR 라이브러리
JAR로 제공되는 Kotlin/Java 라이브러리와 규칙을 번들로 묶으려면 규칙 파일을 최종 JAR의 META-INF/proguard/
디렉터리에 이름과 함께 배치합니다.
예를 들어 코드가 <libraryroot>/src/main/kotlin
에 있는 경우 소비자 규칙 파일을 <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro
에 배치하면 규칙이 출력 JAR의 올바른 위치에 번들로 묶입니다.
규칙이 META-INF/proguard
디렉터리에 있는지 확인하여 최종 JAR이 규칙을 올바르게 번들로 묶었는지 확인합니다.
다양한 축소 도구 지원 (고급)
특정 압축 도구 버전뿐만 아니라 대상별 압축 도구 (R8 또는 ProGuard)에 맞게 규칙을 조정할 수 있습니다. 이렇게 하면 라이브러리가 새 압축기 버전을 사용하는 프로젝트에서 최적으로 작동하는 동시에 이전 압축기 버전이 있는 프로젝트에서 기존 규칙을 계속 사용할 수 있습니다.
타겟팅된 축소 규칙을 지정하려면 아래에 설명된 대로 AAR 또는 JAR 라이브러리 내 특정 위치에 이를 포함해야 합니다.
In an AAR library:
consumer-proguard-rules.pro (legacy location)
classes.jar
└── META-INF
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
In a JAR library:
META-INF
├── proguard/<ProGuard-rules-file> (legacy location)
└── com.android.tools (targeted shrink rules location)
├── r8-from-<X>-upto-<Y>/<R8-rules-file>
└── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>
즉, 타겟팅된 축소 규칙은 JAR의 META-INF/com.android.tools
디렉터리 또는 AAR의 classes.jar
내 META-INF/com.android.tools
디렉터리에 저장됩니다.
이 디렉터리 아래에는 r8-from-<X>-upto-<Y>
또는 proguard-from-<X>-upto-<Y>
형식의 이름을 가진 여러 디렉터리가 있을 수 있으며, 이는 디렉터리 내의 규칙이 어떤 버전의 어떤 압축 도구용으로 작성되었는지 나타냅니다.
-from-<X>
및 -upto-<Y>
부분은 선택사항이며, <Y>
버전은 배타적이며, 버전 범위는 연속적이어야 합니다.
예를 들어 r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0
및 r8-from-8.2.0
는 유효한 타겟팅 축소 규칙 집합을 형성합니다. r8-from-8.0.0-upto-8.2.0
디렉터리의 규칙은 버전 8.0.0부터 버전 8.2.0(제외)까지 R8에서 사용됩니다.
Android Gradle 플러그인은 이 정보를 바탕으로 일치하는 R8 디렉터리에서 규칙을 선택합니다. 라이브러리가 타겟팅된 축소 규칙을 지정하지 않으면 Android Gradle 플러그인이 기존 위치(AAR의 경우 proguard.txt
, JAR의 경우 META-INF/proguard/<ProGuard-rules-file>
)에서 규칙을 선택합니다.