【问题标题】:How to exempt a library module from pro-guard in android gradle如何从 android gradle 中的 pro-guard 中免除库模块
【发布时间】:2023-04-03 21:51:01
【问题描述】:

我的 Android 应用的发布版本崩溃并出现以下异常

java.lang.NoSuchMethodError: no static or non-static method "Lcom/mm/android/dhproxy/client/DHProxyClient;.InitWithName(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)I"

在调试版本中没有发现这个错误,因此我猜是因为 proguard。

上述类位于也使用 JNI 库的模块之一中。 我的 app 模块 文件的 proguard-rules 在下面

-keepattributes InnerClasses
-dontoptimize
-keep class com.mm.android.dhproxy.client.DHProxyClient
-keepclasseswithmembernames class * {
    native <methods>;
}
-keep class mypackage.MyCallbackClass {
    void myCallbackMethod(java.lang.String);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-printmapping build/outputs/mapping/release/mapping.txt

相关模块的 build.gradle 文件如下

应用插件:'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    compileOptions.encoding = 'ISO-8859-1'

    defaultConfig {

        minSdkVersion 14
        targetSdkVersion 23
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile files('libs/IPlaySDK.jar')
    compile files('libs/ToUProxy.jar')
}

即使在添加-keep class com.mm.android.dhproxy.client.DHProxyClient 行之后,我也可以看到usage.txt 文件包含以下条目

com.mm.android.dhproxy.client.DHProxyClient:
    29:35:public boolean initWithName(java.lang.String,int,java.lang.String,java.lang.String)
    64:69:public int delPort(int)
    136:141:public int queryRate(int,com.mm.android.dhproxy.client.DHProxyRateParam)
    158:163:public int p2pSetOption(int,int)
    180:185:public int p2pGetOption(int)
    192:197:public int exit()
    private native int InitWithName(java.lang.String,int,java.lang.String,java.lang.String)
    private native int DelPort(int,int)
    private native int P2PSetOption(int,int,int)
    private native int P2PGetOption(int,int)
    private native int QueryRate(int,com.mm.android.dhproxy.client.DHProxyRateParam,int)
    private native int Exit(int)
com.mm.android.dhproxy.client.DHProxyRateParam

提前致谢。

【问题讨论】:

    标签: java android android-gradle-plugin android-proguard


    【解决方案1】:

    解决方案是查找需要豁免的方法和类,并将它们添加到proguard规则中,如下所示(这里我需要将文件保留在类com.mm.**和com.company.*中* 其中 ** 充当野生字符

    -keep class com.mm.** {*;}
    -keep class com.company.** {*;}
    -keepclassmembers  class com.mm.** {*;}
    -keepclassmembers  class com.company.** {*;}
    

    【讨论】:

      【解决方案2】:

      如果您在主项目/应用程序中使用外部/单独的源库,则不应在库模块上使用 proguard。相反,您替换以下内容,

      buildTypes {
          release {
              minifyEnabled true
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
          }
          debug {
              minifyEnabled false
          }
      }
      

      使用以下内容(在 library/libraries 的 build.gradle 中):

      buildTypes {
          release {
              consumerProguardFiles 'proguard-project.txt'
          }
      }
      

      其中 proguard-project.txt 是包含库项目的 proguard 规则的文件。在构建应用程序时(在调试或发布模式下),编译器将处理所有规则(在库和应用程序中)。

      来源:这个stackoverflow answer

      【讨论】:

        【解决方案3】:

        您能否尝试将 minifyEnabled 设置为 true 并使用以下命令生成发布版本。

        ./gradlew assembleRelease 如果你使用的是 mac gradlew assembleRelease 如果你使用的是寡妇

        运行命令后检查构建,看看它是否有效

        【讨论】:

        • 嗯,我希望图书馆免于缩小过程
        • 我认为如果你不让你 minifyenabled true 你的 proguard 将被忽略。您是否使用我提到的命令生成了发布版本?
        • 发布 { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' }
        猜你喜欢
        • 1970-01-01
        • 2016-02-13
        • 1970-01-01
        • 2017-10-08
        • 1970-01-01
        • 1970-01-01
        • 2017-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多