Android & ProGuard

8993 단어
참조 링크 선호 공식 문서 >>
  • 켜기
  • 구성 방법
  • 조정 방법
  • 시작하기 전에 ProGuard에 대한 자신의 이해를 말하자면 ProGuard를 시작하는 성가비는 비교적 적다. 안전에 있어서 간단한 혼동은 반번역을 막을 수 없지만 디버깅과 교체의 문제를 가져왔다(프로젝트 설정에 대한 혼동 규칙, 승급/제3자 라이브러리 도입에 문제가 있을 수 있다).다른 한편, 많은 앱의 가치는 그 자체의 논리에 의존하지 않고 대응하는 백엔드/운영에 의존하고 그 자체의 핵심 코드는 os 파일에 넣고 자바 코드를 보강하여 역컴파일의 난이도를 높여야 한다.물론 ProGuard는 자원 파일을 압축하여 APK 크기를 줄이는 작용도 하는데 여기서도 ProGuard의 작용을 완전히 부인하는 것은 아니다.
    열다
    android {
        buildTypes {
            release {
                minifyEnabled true
                shrinkResources true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
  • proguardFiles: /tools/proguard/proguard-android.txt은 기본 구성입니다.app/proguard-rules.pro은 우리가 정의한 규칙의 파일이다.
  • app/build.gradle: 서로 다른build type에 서로 다른 설정을 설정합니다.
  • minifyEnabled: 무효한 클래스, 클래스 구성원, 방법, 속성 등을 제거한다.유형명, 속성명, 방법명을 간단명료하고 무의미한 명칭
  • 으로 바꾸다
  • shrinkResources: 자원을 삭제/통합하고 drawable/layout에서 인용되지 않은 파일의 내용을 비우고 보존한다.이름이 같은 자원은 중복 자원으로 간주되고 합병된다.주의: 자원을 삭제하면 문제가 발생하기 쉬우므로 삭제된 자원을 찾아 res/raw/keep.xml
  • 이라고 표시해야 한다.
    
    
    
    
    

    구축이 완료되면 /build/outputs/mapping/release/에서 관련 파일을 찾을 수 있습니다. dump.txt: APK의 모든 클래스 파일의 내부 구조를 설명합니다.mapping.txt: 원시와 혼동된 클래스, 방법과 필드 이름 사이의 전환을 제공합니다.seeds.txt: 혼동되지 않은 클래스와 구성원을 열거합니다.usage.txt: APK에서 제거된 코드를 나열합니다.
    프로비저닝
    사용자 정의 혼동 규칙의 형식은 다음과 같습니다.
    [    ]  {
        [  ] 
    }
    
  • [ ]

  • 명령하다
    설명
    -dontwarn
    가방 이름을 지정하는 혼동을 알려주지 않습니다. 가방 Warning
    -keep
    클래스와 구성원이 제거되거나 이름이 바뀌는 것을 방지합니다
    -keepnames
    클래스 및 구성원 이름 바꾸기 방지
    -keepclassmembers
    구성원이 제거되거나 이름이 변경되지 않도록 방지
    -keepnames
    구성원 이름 바꾸기 방지
    -keepclasseswithmembers
    지정한 클래스와 구성원을 보존합니다. 압축 단계에서 삭제되지 않았을 때.
    -keepclasseswithmembernames
    이 구성원을 가진 클래스와 구성원의 이름을 바꾸는 것을 방지합니다 , :
    • ( )
      -dontnote retrofit2.Platform
    • 액세스 수정자(public,protected,private)-keep public class * extends android.app.Fragment
    • 와일드카드 문자 *, 임의의 길이 문자와 일치하지만 패키지 이름 구분자 없음(.)
    • 와일드카드 문자 **, 임의의 길이 문자와 일치하며 패키지 이름 구분자(.) 포함-dontwarn com.tencent.bugly.**
    • extends, 클래스를 지정할 수 있는 기본 클래스 -keep public class * extends android.app.Fragment
    • implement, 특정 인터페이스의 클래스 일치 -keep public class * implements com.bumptech.glide.module.GlideModule
    • 달러, 내부 클래스
    • [ ]은 클래스 구성원과 관련된 한정 조건을 지정하여 사용할 수 있다.
    • 모든 구조기 매칭 public ();
    • 모든 필드 일치
    • 모든 방법 일치
    • #          @org.greenrobot.eventbus.Subscribe      
      -keepclassmembers class ** {
          @org.greenrobot.eventbus.Subscribe ;
      }
      
    • 와일드카드 문자*, 임의의 길이 문자와 일치하지만 패키지 이름 구분자 없음(.)
    • 와일드카드 문자**로 길이와 상관없이 패킷 이름 구분자(.)
    • 와일드카드 ***, 모든 매개변수 유형 일치
    • ..., 임의의 길이의 임의의 매개 변수와 일치합니다.void test(…)
    • 액세스 수정자(public,protected,private)
    • 일반적인 쓰기 방법은 다음과 같습니다.
      #       
      -keep public class name.huihui.example.Test { *; }
      
      #           
      -keep class name.huihui.test.** { *; }
      
      #         
      -keep public class * extends name.huihui.example.Test { *; }
      
      #           “model”      
      -keep public class **.*model*.** {*;}
      
      #          
      -keep class * implements name.huihui.example.TestInterface { *; }
      
      #           
      -keepclassmembers class name.huihui.example.Test { 
        public (); 
      }
      
      #            
      -keepclassmembers class name.huihui.example.Test { 
        public void test(java.lang.String); 
      }
      

      조정
      혼동의 규칙은 대부분 고정적이며 프로젝트 참조의 프레임워크, 사용된 기술에 따라 규칙을 조정하는 데 중점을 두고 있습니다.
    • 제3자 라이브러리에 필요한 혼동 규칙.정규적인 제3자 라이브러리는 일반적으로 문서에 접속하는 데 필요한 혼동 규칙을 작성하고 사용할 때 추가에 주의해야 한다.
    • 이 실행될 때 동적으로 바뀐 코드, 예를 들어 반사.비교적 전형적인 예는 json과 서로 전환되는 실체류이다.만약에 프로젝트 명명 규범이 실체 클래스를 Model 패키지 아래에 두도록 요구한다면 이와 같은 코드를 추가하여 모든 실체 클래스를 유지할 수 있다. -keep public class **.*Model*.** {*;}
    • JNI에서 호출된 클래스.
    • WebViewJavaScript 호출 방법
    • #   annotation,    @JavascriptInterface 
      -keepattributes *Annotation*
      
      #    javascript       
      -keepattributes JavascriptInterface
      
      # #package#       
      #-keepclassmembers #package#.JSInterface {
      #    ;
      #}
      
    • Layout 레이아웃에 사용되는 View 구조 함수, android:onClick 등.
    • #       View   get   set     
      -keepclassmembers public class * extends android.view.View {
         void set*(***);
         *** get*();
      }
      

      질문
      Note: there were 8 references to unknown classes.
      You should check your configuration for typos.
      ([http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass](http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass))
      Note: there were 272 unkept descriptor classes in kept class members.
      You should consider explicitly keeping the mentioned classes
      (using '-keep').
      ([http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass](http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass))
      Note: there were 75 unresolved dynamic references to classes or interfaces.
      You should check if you need to specify additional program jars.
      ([http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass](http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass))
      Warning: there were 11 unresolved references to classes or interfaces.
      You may need to add missing library jars or update their versions.
      If your code works fine without the missing classes, you can suppress
      the warnings with '-dontwarn' options.
      ([http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass](http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass))
      Warning: Exception while processing task java.io.IOException: Please correct the above warnings first.
      

      Warning에서 해석되지 않은 11개의 클래스나 인용을 언급하고 두 가지 해결 방안을 제시한다.방안 1: 잃어버린 라이브러리를 추가하거나 버전을 업데이트해야 할 수도 있습니다.방안2: 만약 당신이 지금 코드가 잘 작동하고 있다면, 그것들이 없어도 상관없다면, 당신은 -dontwarn을 사용하여 이러한 경고를 금지할 수 있습니다.
      특정 클래스 또는 참조가 로그에 나타납니다.
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.OpenSSLProvider
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.OpenSSLProvider
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      Warning: okhttp3.internal.platform.ConscryptPlatform: can't find referenced class org.conscrypt.Conscrypt
      

      상기 예에서 유형 okhttp3.internal.platform.ConscryptPlatformorg.conscrypt.OpenSSLProvider을 인용했지만 혼동 압축 후 찾을 수 없었다.항목에 상위 org.conscrypt.OpenSSLProvider이 실제로 사용되지 않으면 다음과 같은 규칙을 통해 경고를 억제할 수 있습니다.
      -dontwarn org.conscrypt.*
      

      또는
      -dontwarn okhttp3.internal.platform.ConscryptPlatform
      
    • 이 운행할 때 문제라는 가장 번거로운 것은 이런 문제가 비교적 깊이 숨어 있을 수 있기 때문에 철저한 회귀 테스트를 제외하고는 이 중의 원리를 이해해야만 문제를 효과적으로 줄일 수 있다.혼동 규칙을 설정할 때 동적 변경된 코드, 반사, js 호출 등 방법/클래스는 혼동될 수 없습니다. 그렇지 않으면 실행할 때 오류가 발생합니다.구체적으로 Retrofit 등 네트워크 프레임워크나 Gson으로 json을 실체류로 해석할 때 -keep을 사용하지 않으면 실체류를 표시하지 않으면 실체류의 필드 이름이 혼동되어 예상한 필드에 해석할 수 없다.

    • 부분적으로 Android 개발자에게 작성된 혼동 사용 설명서 참조

    좋은 웹페이지 즐겨찾기