2011-07-01 52 views
25

我是新来的使用Proguard,所以我可能犯了一个新手的错误。我有一个应用程序,在我运行发布版本(使用Proguard进行混淆处理)后,它迅速崩溃。我相信我已经把它缩小到了它似乎混淆了我的参考库的事实。在我的情况下,我的参考库用于定义我正在使用Google Protobuffers与其他设备通信的消息类。我正在使用,蚂蚁释放。 我ProGuard的配置是:使用proguard的Android混淆应用程序会保持混淆库罐 - 或者它是什么?

-optimizationpasses 5 
-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 

-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.licensing.ILicensingService 

-keepclasseswithmembernames class * 
{ 
    native <methods>; 
} 

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

-keepclasseswithmembernames 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 *; 
} 

在我的Ant build.xml文件我有以下定义:

<target name="-obfuscate" unless="do.not.compile"> 
    <if condition="${proguard.enabled}"> 
     <then> 
      <property name="obfuscate.absolute.dir" location="${out.absolute.dir}/proguard" /> 
      <property name="preobfuscate.jar.file" value="${obfuscate.absolute.dir}/original.jar" /> 
      <property name="obfuscated.jar.file" value="${obfuscate.absolute.dir}/obfuscated.jar" /> 

      <!-- input for dex will be proguard's output --> 
      <property name="out.dex.input.absolute.dir" value="${obfuscated.jar.file}" /> 

      <!-- Add Proguard Tasks --> 
      <property name="proguard.jar" location="${android.tools.dir}/proguard/lib/proguard.jar" /> 
      <taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="${proguard.jar}" /> 

      <!-- Set the android classpath Path object into a single property. It'll be 
       all the jar files separated by a platform path-separator. 
      --> 
      <property name="android.libraryjars" refid="android.target.classpath"/> 

      <!-- Build a path object with all the jar files that must be obfuscated. 
       This include the project compiled source code and any 3rd party jar 
       files. 
      --> 
      <path id="project.jars.ref"> 
       <pathelement location="${preobfuscate.jar.file}" /> 
       <path refid="jar.libs.ref" /> 
      </path> 

      <!-- Set the project jar files Path object into a single property. It'll be 
       all the jar files separated by a platform path-separator. 
      --> 
      <property name="project.jars" refid="project.jars.ref" /> 

      <mkdir dir="${obfuscate.absolute.dir}" /> 
      <delete file="${preobfuscate.jar.file}" /> 
      <delete file="${obfuscated.jar.file}" /> 
      <jar basedir="${out.classes.dir}" destfile="${preobfuscate.jar.file}" /> 
      <proguard> 
       @${proguard.config} 
       -injars ${project.jars} 
       -outjars ${obfuscated.jar.file} 
       -libraryjars ${android.libraryjars} 
       -dump ${obfuscate.absolute.dir}/dump.txt 
       -printseeds ${obfuscate.absolute.dir}/seeds.txt 
       -printusage ${obfuscate.absolute.dir}/usage.txt 
       -printmapping ${obfuscate.absolute.dir}/mapping.txt 
      </proguard> 
     </then> 
    </if> 
</target> 

<!-- Converts this project's .class files into .dex files --> 
<target name="-dex" depends="compile, -post-compile, -obfuscate" 
     unless="do.not.compile"> 
    <if condition="${manifest.hasCode}"> 
     <then> 
      <dex-helper /> 
     </then> 
     <else> 
      <echo>hasCode = false. Skipping...</echo> 
     </else> 
    </if> 
</target> 

<!-- Puts the project's resources into the output package file 
    This actually can create multiple resource package in case 
    Some custom apk with specific configuration have been 
    declared in default.properties. 
    --> 
<target name="-package-resources"> 
    <echo>Packaging resources</echo> 
    <aapt executable="${aapt}" 
      command="package" 
      versioncode="${version.code}" 
      debug="${build.packaging.debug}" 
      manifest="AndroidManifest.xml" 
      assets="${asset.absolute.dir}" 
      androidjar="${android.jar}" 
      apkfolder="${out.absolute.dir}" 
      resourcefilename="${resource.package.file.name}" 
      resourcefilter="${aapt.resource.filter}"> 
     <res path="${resource.absolute.dir}" /> 
     <!-- <nocompress /> forces no compression on any files in assets or res/raw --> 
     <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw --> 
    </aapt> 
</target> 

<!-- Packages the application and sign it with a debug key. --> 
<target name="-package-debug-sign" depends="-dex, -package-resources"> 
    <package-helper 
      output.filepath="${out.debug.unaligned.file}" /> 
</target> 

<!-- Packages the application without signing it. --> 
<target name="-package-release" depends="-dex, -package-resources"> 
    <package-helper 
      output.filepath="${out.unsigned.file}"/> 
</target> 
    <target name="-set-release-mode"> 
     <!-- release mode is only valid if the manifest does not explicitly 
      set debuggable to true. default is false. 
      We actually store build.packaging.debug, not build.release --> 
     <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable" 
       output="build.packaging.debug" default="false"/> 

     <!-- Enable proguard --> 
     <property name="proguard.enabled" value="true"/> 
     <property name="proguard.config" value="proguard.cfg"/> 

     <!-- signing mode: release --> 
     <property name="build.signing.debug" value="false" /> 

     <if condition="${build.packaging.debug}"> 
      <then> 
       <echo>*************************************************</echo> 
       <echo>**** Android Manifest has debuggable=true ****</echo> 
       <echo>**** Doing DEBUG packaging with RELEASE keys ****</echo> 
       <echo>*************************************************</echo> 
      </then> 
      <else> 
       <!-- property only set in release mode. 
        Useful for if/unless attributes in target node 
        when using Ant before 1.8 --> 
       <property name="build.mode.release" value="true"/> 
      </else> 
     </if> 
    </target> 

    <target name="release" 
      depends="-set-release-mode, -release-obfuscation-check, -package-release, -release-prompt-for-password, -release-nosign" 
       if="has.keystore" 
       description="Builds the application. The generated apk file must be signed before 
          it is published."> 
     <!-- Signs the APK --> 
     <echo>Signing final apk...</echo> 
     <signjar 
       jar="${out.unsigned.file}" 
       signedjar="${out.unaligned.file}" 
       keystore="${key.store}" 
       storepass="${key.store.password}" 
       alias="${key.alias}" 
       keypass="${key.alias.password}" 
       verbose="${verbose}" /> 

     <!-- Zip aligns the APK --> 
     <zipalign-helper in.package="${out.unaligned.file}" 
            out.package="${out.release.file}" /> 
     <echo>Release Package: ${out.release.file}</echo> 
    </target> 

我会很感激的任何想法。我从在线模板中复制了大部分构建和proguard配置,我怀疑我实际上正在使用Proguard来混淆库jar或者我配置了一些lisconfigured。 我看到在我的cmd窗口下面的输出在构建的末尾:

[proguard] Writing output... 
[proguard] Preparing output jar [C:\Workspace\UI\MyApp\build\proguard\obfuscated.jar] 
[proguard] Copying resources from program jar [C:\Workspace\UI\MyApp\build\proguard\original.jar] 
[proguard] Copying resources from program jar [C:\Workspace\UI\MyApp\libs\libmessaging.jar] 
[proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [libmessaging.jar:META-INF/MANIFEST.MF]) 
[proguard] Copying resources from program jar [C:\Workspace\UI\MyApp\libs\protobuf-2.3.0.jar] 
[proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [protobuf-2.3.0.jar:META-INF/MANIFEST.MF]) 
[proguard] Printing classes to [C:\Workspace\Riptide1_1_ptr_74\WPG_HAWKSBILL\UI\MyApp\build\proguard\dump.txt]... 

谢谢!

回答

43

您在Proguard配置中评论了您的库jar指令。
变化:

# -libraryjars /libs/protobuf-2.3.0.jar 
# -libraryjars /libs/libmessaging.jar 

到:

-libraryjars /libs/protobuf-2.3.0.jar 
-libraryjars /libs/libmessaging.jar 

(然后不打扰定义你的build.xml你的jar包)

编辑:
我找到了另一种方式来让Proguard离开图书馆罐子本身就是要求它保留他们的包装名称,例如:

-keep class javax.** { *; } 
-keep class org.** { *; } 
-keep class twitter4j.** { *; } 
+0

我知道我让他们注释掉 - 我得到了各种输出,所以我评论他们 - 但我没有注意到,我也让他们在构建中引用。我会试一试!所以我需要从我的构建文件中删除行和-libraryjars $ {android.libraryjars}?谢谢! – bursk

+0

我改变了我的答案,添加了其他东西,我也做了...见上面。 –

+0

感谢您的帮助。我仍然要失去一些东西。我编辑了我的proguard.cfg以显示我如何取消注释了库和添加了-keeps。我从目标名称=“my build.xml”中注释掉了(-libraryjars $ {android.libraryjars})和( ) -obfuscate“,但是当我尝试释放ant时,我得到了libmessaging.jar中所有类的错误,如”无法找到引用的类java.lang.String“和”库类的重复定义“。 – bursk

3

当proGuard加密jsoup lib时,我遇到了类似的问题。我固定它通过添加以下到我的proguard的-rules.txt

-keep class org.jsoup** { 
    *; 
} 

所以的build.gradle将结束与以下部分:

release { 
    minifyEnabled true 
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 
}