如何在android gradle中免除库模块和pro-guard

dmS*_*azi 5 java android android-gradle-plugin android-proguard

我的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库的模块中.我的应用程序模块文件的proguard规则如下

-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
Run Code Online (Sandbox Code Playgroud)

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

apply plugin:'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')
}
Run Code Online (Sandbox Code Playgroud)

即使添加了行后,-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
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Zax*_*ter 5

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

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

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

buildTypes {
    release {
        consumerProguardFiles 'proguard-project.txt'
    }
}
Run Code Online (Sandbox Code Playgroud)

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

资料来源:这个stackoverflow答案


dmS*_*azi 5

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

-keep class com.mm.** {*;}
-keep class com.company.** {*;}
-keepclassmembers  class com.mm.** {*;}
-keepclassmembers  class com.company.** {*;}
Run Code Online (Sandbox Code Playgroud)