我目前正在开发一个Android项目,其中正在使用Android NDK在C中进行一些计算。

只要我不运行proguard,我的应用程序就可以正常工作,但是当我运行proguard时,方法“ reportProgress”将被proguard删除。该方法是扩展AsyncTask的私有内部类的一部分

private class CalculateTask extends AsyncTask


我使用对CalculateTask实例的引用来调用本机代码。然后,本机代码使用JNI中的以下代码调用此类中的成员

jclass taskClass = (*env)->GetObjectClass(env, task);
jmethodID reportProgressMid = (*env)->GetMethodID(env, taskClass, "reportProgress", "(Ljava/lang/String;I)Z");


其中task是对CalculateTask实例的引用。我很难告诉Proguard不要剥离

public boolean reportProgress(String, int)


方法,仅通过JNI调用。

到现在为止,我已经采取了以下方法,但没有一个达到目的:

保持整个课堂:

-keep class MYPACKAGENAME.CalculateScreen$CalculateTask


通过执行以下操作仅保留上述方法:

-keep class MYPACKAGENAME.CalculateScreen$CalculateTask {
    public boolean reportProgress(java.lang.String,int);
}


或这个:

-keepclassmembers class MYPACKAGENAME.CalculateScreen$CalculateTask {
    public boolean reportProgress(java.lang.String,int);
}


使用注释(重复使用Google AdMob注释):

-keep class MYPACKAGENAME.CalculateScreen$CalculateTask {
    @com.google.android.gms.common.annotation.KeepName <methods>;
}


或这个:

-keepclassmembers class MYPACKAGENAME.CalculateScreen$CalculateTask {
    @com.google.android.gms.common.annotation.KeepName <methods>;
}


我的proguard配置基于随Android SDK一起分发的“优化”,名为proguard-android-optimize.txt。

请注意,proguard是通过Gradle运行的,并且我已确保proguard任务已清理并重新运行。

最佳答案

您的第二个和第三个配置应适用于这种情况:

-keepclassmembers class MYPACKAGENAME.CalculateScreen$CalculateTask {
    public boolean reportProgress(java.lang.String,int);
}


您应该检查类名和方法名是否有错别字。您还应该检查该方法是否真的是公开的。

您可以验证该方法是否保留在bin/proguard/seeds.txt中。

您还可以使用javap检查编译的输入类和已处理的输出类。

10-07 19:30
查看更多