2011-07-01 78 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' 
}