有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在安卓 gradle中将库模块从proguard中免除

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

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

在调试版本中找不到此错误,因此我想这是因为proguard

上述类位于其中一个也使用JNI库的模块中。 下面是应用程序模块文件的proguard规则

-keepattributes InnerClasses
-dontoptimize
-keep class com.mm.安卓.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

建造。相关模块的gradle文件如下所示

应用插件:com。安卓图书馆的

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

    defaultConfig {

        minSdkVersion 14
        targetSdkVersion 23
    }

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

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

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

com.mm.安卓.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.安卓.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.安卓.dhproxy.client.DHProxyRateParam,int)
    private native int Exit(int)
com.mm.安卓.dhproxy.client.DHProxyRateParam

提前谢谢


共 (3) 个答案

  1. # 1 楼答案

    如果在主项目/应用程序中使用外部/单独的源库,则不应在库模块上使用proguard。取而代之的是,替换以下内容:

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

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

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

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

    资料来源:本stackoverflow answer

  2. # 2 楼答案

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

    -keep class com.mm.** {*;}
    -keep class com.company.** {*;}
    -keepclassmembers  class com.mm.** {*;}
    -keepclassmembers  class com.company.** {*;}
    
  3. # 3 楼答案

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

    /gradlew AssemblereRelease如果您使用mac gradlew AssemblereRelease如果您使用widows

    运行该命令后检查生成,看看它是否有效