Proguard:JNI调用JAVA方法只发生一次(而不是多次)

时间:2016-06-30 13:12:03

标签: java android java-native-interface proguard android-proguard

我遇到Proguard混淆问题。我的(内联)java方法只从JNI调用一次,尽管它是从循环中调用的。

循环的第一次迭代运行良好,但在第二次迭代(textureCount> 1)上,应用程序似乎没有输入getTexture方法 - 这导致我的应用程序崩溃{{ 1}}因为Texture::create(env, textureObject)为NULL。

要说清楚 - 未启用textureObject - 一切正常

在我的JNI代码中

ProGuard

proguard.cfg

JNIEXPORT void JNICALL
Java_com_example_MyApp_initApplicationNative(JNIEnv* env, jobject obj) {

    // Handle to the activity class:
    jclass activityClass = env->GetObjectClass(obj);

    jmethodID getTextureCountMethodID = env->GetMethodID(activityClass, "getTextureCount", "()I");
    if (getTextureCountMethodID == 0) {
        LOG("Function getTextureCount() not found.");
        return;
    }

    textureCount = env->CallIntMethod(obj, getTextureCountMethodID);
    if (!textureCount) {
        LOG("getTextureCount() returned zero.");
        return;
    }

    textures = new Texture*[textureCount];

    jmethodID getTextureMethodID = env->GetMethodID(activityClass, "getTexture",
                                            "(I)Lcom/example/MyApp/Texture;");

    if (getTextureMethodID == 0) {
        LOG("Function getTexture() not found.");
        return;
    }

    // Register the textures
    for (int i = 0; i < textureCount; ++i) 
    {
        jobject textureObject = env->CallObjectMethod(obj, getTextureMethodID, i);
        if (textureObject == NULL) {
            LOG("GetTexture() returned zero pointer");
            return;
        }
        textures[i] = Texture::create(env, textureObject);
    }

}

MyApp.java

-optimizationpasses 5
-dontusemixedcaseclassnames
-useuniqueclassmembernames

-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# will keep line numbers and file name obfuscation
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

##########  default settings #########

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.billing.IInAppBillingService
-keep public class com.android.vending.licensing.ILicensingService

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.content.Context {
    public void *(android.view.View);
    public void *(android.view.MenuItem);
}

-keepclasseswithmembernames,includedescriptorclasses class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.MyApp {
    native <methods>;
    int getTextureCount();
    com.example.MyApp.Texture getTexture(int);
}

编辑 - 解决方案

解决这个问题的原因可能是我没有通过Proguard保存Texture类名 起初我用这种方式,只保留相关的班级成员:

/**
 * Returns the texture object at the specified index.
 */
public Texture getTexture(int i) {
    return mTextures.elementAt(i);
}

但当我把它改为:

-keepclassmembers class **.Texture {
    native <methods>;
    byte[] getData();
    int mWidth;
    int mHeight;
    ....
    }
这一切都成功了。 我必须说,我不确定我能解释得多,我只知道来自-keep class **.Texture { *; } getTexture()命令的返回值现在正在完美运行,没有例外。

我尽量不尽可能地使用jclass textureClass = env->GetObjectClass(textureObject);,但在这里我不确定我有更好的解决方案。

0 个答案:

没有答案