ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Retrofit proguard 적용 시 크래시 발생과 R8 오류 해결
    Android 2024. 8. 1. 10:24
    반응형

     

    //  Firebase Crashlytics 발췌
    1. Unable to create call adapter for interface sf.b for method h.a
    2. Call return type must be parameterized as Call<Foo> or Call<? extends Foo>

     

     

    앱을 잘 만들고, 심사 후 플레이스토어에 등록이 됐다.

    근데 갑자기 위 에러가 발생하면서 배포된 앱이 강제종료가 된다면 ?

     

    슬픕니다

     

     

    Debug 모드에서는 프로가드가 적용되지 않아 확인하지 못했고,

    Release 모드로 배포하면서 프로가드가 적용되며.. 에러가 발생하게 된다.

     

     

     

    그럼 Retrofit 에 Proguard 를 설정해주면 되겠네 !

     

    라고 생각하며, Retrofit Github 를 찾아가서 파일을 살펴보자.

     

    # Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
    # EnclosingMethod is required to use InnerClasses.
    -keepattributes Signature, InnerClasses, EnclosingMethod
    
    # Retrofit does reflection on method and parameter annotations.
    -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
    
    # Keep annotation default values (e.g., retrofit2.http.Field.encoded).
    -keepattributes AnnotationDefault
    
    # Retain service method parameters when optimizing.
    -keepclassmembers,allowshrinking,allowobfuscation interface * {
        @retrofit2.http.* <methods>;
    }
    
    # Ignore annotation used for build tooling.
    -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
    
    # Ignore JSR 305 annotations for embedding nullability information.
    -dontwarn javax.annotation.**
    
    # Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
    -dontwarn kotlin.Unit
    
    # Top-level functions that can only be used by Kotlin.
    -dontwarn retrofit2.KotlinExtensions
    -dontwarn retrofit2.KotlinExtensions$*
    
    # With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
    # and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
    -if interface * { @retrofit2.http.* <methods>; }
    -keep,allowobfuscation interface <1>
    
    # Keep inherited services.
    -if interface * { @retrofit2.http.* <methods>; }
    -keep,allowobfuscation interface * extends <1>
    
    # With R8 full mode generic signatures are stripped for classes that are not
    # kept. Suspend functions are wrapped in continuations where the type argument
    # is used.
    -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
    
    # R8 full mode strips generic signatures from return types if not kept.
    -if interface * { @retrofit2.http.* public *** *(...); }
    -keep,allowoptimization,allowshrinking,allowobfuscation class <3>
    
    # With R8 full mode generic signatures are stripped for classes that are not kept.
    -keep,allowobfuscation,allowshrinking class retrofit2.Response

     

    . . . 아니 너무 내용이 많잖아 ?!

     

     

    -keep class retrofit2.** { *; }
    -keepattributes *Annotation*

     

    -keep 을 통해 retrofit2 class의 난독화를 방지해버리는 방법을 사용하기로 결정 !

    더 다양한 난독화 규칙이 궁금하다면, 효송송 계란탁 - Proguard 적용기 를 참고해두데용

     

     

    .

    .

    .

    근데 ... 이렇게 적용해도 계속 강제종료되는 이슈가 발생  ..

    혹시나 싶어 retrofit github 의 프로가드를 전체 적용해봐도 똑같았다.

     

     

     

     

    Retrofit Github 내용을 다시 살펴보니, 하단에서 R8 규칙에 대해 다루고 있는데

    yes , , , , AGP 8.0 부터 R8 의 동작방식이 변경되었다고 한다 .

    ※ R8 FAQ 참고 (GSON 관련 TroubleShooting 포함)

     

     

     

    기존에는 R8이 프로가드와 동작할 때 호환모드로 작동했는데,

    AGP 8.0 부터는 기본적으로 full mode 로 작동하며 더 강력하게 최적화를 진행한다고 한다.

     

    정말 간단하게 ...

    gradle.properties 파일에 "android.enableR8.fullMode=false" 한 줄 추가헀더니 깔끔하게 문제 해결

     

     

     

     

    반응형
Designed by Tistory.