Android Proguard问题 - 当跳过混淆时仍会出现“java.io.IOException:无法处理类…”错误

16

我正在使用Android Studio和Proguard构建一个Android应用程序,我的项目中包含一个库jar(na.jar)。由于来自na.jar的某些类在构建过程中给我带来了错误,因此我想跳过对该库进行混淆和预验证。因此,在我的proguard配置文件中,我有以下选项:

-dontpreverify 

# com.na, org.json are packages in na.jar, don't obfuscate the code in these packages
-keep class com.na.** { *; } 
-keep interface com.na.** { *; } 
-keep class org.json.** { *; } 
-keep interface org.json.** { *; } 

然而,在构建过程中,我仍然遇到与na.jar中错误类相关的以下错误。
Caused by: java.io.IOException: Can't read [C:\StudioProjects\PBActivity\pBActivity\libs\na.jar(;;;;;;!META-INF/MANIFEST.MF)] (Can't process class [com/na/util/BinConverter.class] (256))
    at proguard.InputReader.readInput(InputReader.java:188)
    at proguard.InputReader.readInput(InputReader.java:158)
    at proguard.InputReader.readInput(InputReader.java:136)
    at proguard.InputReader.execute(InputReader.java:66)
    at proguard.ProGuard.readInput(ProGuard.java:207)
    at proguard.ProGuard.execute(ProGuard.java:81)
    at proguard.gradle.ProGuardTask.proguard(ProGuardTask.java:1074)
    at com.android.build.gradle.tasks.AndroidProGuardTask.proguard(AndroidProGuardTask.java:87)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
    ... 62 more
Caused by: java.io.IOException: Can't process class [com/na/util/BinConverter.class] (256)
    at proguard.io.ClassReader.read(ClassReader.java:112)
    at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)
    at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)
    at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:87)
    at proguard.io.JarReader.read(JarReader.java:65)
    at proguard.io.DirectoryPump.readFiles(DirectoryPump.java:65)
    at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:53)
    at proguard.InputReader.readInput(InputReader.java:184)
   ... 70 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 256
    at proguard.classfile.ProgramClass.getString(ProgramClass.java:116)
    at proguard.classfile.io.ProgramClassReader.createAttribute(ProgramClassReader.java:990)
    at proguard.classfile.io.ProgramClassReader.visitProgramMethod(ProgramClassReader.java:206)
    at proguard.classfile.io.ProgramClassReader.visitProgramClass(ProgramClassReader.java:149)
    at proguard.classfile.ProgramClass.accept(ProgramClass.java:358)
    at proguard.io.ClassReader.read(ClassReader.java:91)
    ... 77 more

即使跳过混淆,Proguard仍会读取类和JAR文件吗?我是第一次使用Proguard构建Android应用程序。

更新 #1

-dontpreverify
-dontoptimize
-dontshrink

-keep class com.na.** { *; }
-keep interface com.na.** { *; }
-keep class org.json.** { *; }
-keep interface org.json.** { *; }

是的,混淆只是ProGuard所做的工作的一部分 - 它将继续执行剩余的任务,例如删除未使用的代码等。 - Owais Ali
你能否发布一下你的ProGuard配置现在是什么样子的? - Owais Ali
请参考原帖的更新#1以获取我的当前配置文件。谢谢。 - Nicky
你有联系到谁建立这个库的吗?我也在苦苦挣扎,我会尝试看看能否获取一个新版本的jar。它似乎被打包成一种ProGuard非常不喜欢的方式。最好的方法是找到一个配置,让proguard跳过处理该文件,但我一直没有成功。 - havchr
你检查过文件是否可读吗? - Adliano Alves
显示剩余4条评论
2个回答

2

我也遇到了ProGuard的问题,但是我在GitHub上找到了以下代码,发现更有用。

Build.grade

buildscript {
    repositories {
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
        classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'
    }
}
apply plugin: 'android'
apply plugin: 'android-test'

repositories {
    mavenCentral()
    maven {
        url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.1.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
    }

    signingConfigs {
        debug {
            storeFile file("debug.keystore")
        }

        release {
            storeFile file("project.keystore")
            storePassword "1234"
            keyAlias "Project"
            keyPassword "1234"
        }
    }

    buildTypes {
        release {
            debuggable false
            runProguard true
            signingConfig signingConfigs.release
            proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
        }
    }

    productFlavors {
        defaultFlavor {
            proguardFile 'proguard-rules.txt'
        }
    }

    sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src-gen/main/java']
        }
        instrumentTest.setRoot('src/test')
    }
}

dependencies {

    compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
    compile 'com.android.support:support-v4:19.1.+'
    compile 'de.greenrobot:greendao:1.3.7'
    compile 'com.google.android.gms:play-services:4.4.52'

    testCompile 'junit:junit:4.10'
    testCompile 'org.robolectric:robolectric:2.1.+'
    testCompile 'com.squareup:fest-android:1.0.+'

    instrumentTestCompile 'junit:junit:4.10'
    instrumentTestCompile 'org.robolectric:robolectric:2.1.+'
    instrumentTestCompile 'com.squareup:fest-android:1.0.+'
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}

ProGuard规则

####################################################################################################
    ####################################################################################################
    ####################################################################################################
    ######################################### PROGUARD #################################################
    ####################################################################################################
    ####################################################################################################
    ####################################################################################################

    # This is a configuration file for ProGuard.
    # http://proguard.sourceforge.net/index.html#manual/usage.html
    -dontusemixedcaseclassnames
    -dontskipnonpubliclibraryclasses
    -verbose

    # Optimization is turned off by default. Dex does not like code run
    # through the ProGuard optimize and preverify steps (and performs some
    # of these optimizations on its own).
    #-dontoptimize
    #-dontpreverify

    # If you want to enable optimization, you should include the
    # following:
    -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
    -optimizationpasses 5
    -allowaccessmodification
    #
    # Note that you cannot just include these flags in your own
    # configuration file; if you are including this file, optimization
    # will be turned off. You'll need to either edit this file, or
    # duplicate the contents of this file and remove the include of this
    # file from your project's proguard.config path property.

    -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.BackupAgent
    -keep public class * extends android.preference.Preference
    -keep public class * extends android.support.v4.app.Fragment
    -keep public class * extends android.support.v4.app.DialogFragment
    -keep public class * extends com.actionbarsherlock.app.SherlockListFragment
    -keep public class * extends com.actionbarsherlock.app.SherlockFragment
    -keep public class * extends com.actionbarsherlock.app.SherlockFragmentActivity
    -keep public class * extends android.app.Fragment
    -keep public class com.android.vending.licensing.ILicensingService

    # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
    -keepclasseswithmembernames class * {
     native <methods>;
    }

    -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);
     public void set*(...);
    }

    -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.app.Activity {
     public void *(android.view.View);
    }

    # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
    -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 **.R$* {
     public static <fields>;
    }

    -keep class android.support.v4.app.** { *; }
    -keep interface android.support.v4.app.** { *; }
    -keep class com.actionbarsherlock.** { *; }
    -keep interface com.actionbarsherlock.** { *; }
    # The support library contains references to newer platform versions.
    # Don't warn about those in case this app is linking against an older
    # platform version. We know about them, and they are safe.
    -dontwarn android.support.**
    -dontwarn com.google.ads.**

0

试试这个:

-dontwarn com.na.**
-keep class com.na.** { *; }
-keepattributes Signature
-keepattributes Exceptions

这并没有提供问题的答案。如果要批评或请求作者澄清,请在他们的帖子下留言。-【来自审查】 - Eli Sadoff
他想跳过JAR文件中的类,所以我写了这段代码来帮助他而不是批评他。@EliSadoff - masoud vali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接