2011-07-01 4 views
25

Proguard'ı kullanmakta yeniyim, bu yüzden muhtemelen yeni bir kullanıcı hatası yapıyorum. Bir uygulama var, sürüm oluşturmayı çalıştırdıktan sonra (Proguard'ı şaşırtmak için kullanır) oldukça hızlı bir şekilde çöküyor. Referans kütüphanelerimi gizlemek gibi göründüğüne inanıyorum. Benim durumumda referans kütüphanelerim, Google Protobuffer'ları kullanarak başka bir cihaza iletişim kurmak için kullanıyorum mesaj sınıflarımı tanımlamak için kullanılıyor. Kullanarak yapıyorum, karınca serbest bırakma. Benim proguard yapılandırma: Ben tanımlanan aşağıdaki seçeneklerin benim karınca build.xml dosyasındaProguard kullanarak Android obfuscate uygulaması kütüphane kavanozları gizlemek tutar - ya da?

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

:

<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> 

Ben herhangi bir fikir takdir ediyorum. Yapım ve proguard yapılandırmamın çoğunu çevrimiçi şablonlardan kopyaladım, aslında Proguard'ın kütüphane kavanozlarını gizlemesini istediğimden şüpheleniyorum veya lisconfigured bir şeyim var. Ben inşa sonunda benim cmd penceresinde şu çıktıyı görüyorum:

[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]... 

Teşekkür!

cevap

43

Kitaplık küpü yönergelerinizi Proguard yapılandırmasında yorumlamıştınız.
Değişikliği:

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

için:

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

(ve sonra build.xml Kütüphanenizin kavanoz tanımlayan zahmet etmeyin) DÜZENLEME

:
Ben başka bir yol buldum Proguard'ın kitaplık kavanozlarını tek başına bırakması, paket adlarını korumasını istemek oldu, örn .:

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

:

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

Yani build.gradle aşağıdaki bölümde ile sona erecek: Benim proguard-rules.txt aşağıdaki ekleyerek sabit yorumladı - her türlü çıktıyı elde ettim, bu yüzden onları yorumladım - ama aynı zamanda inşada referans gösterdiğimi fark etmemiştim. Bunu deneyeceğim! Bu yüzden benim yapı dosyasından ve -libraryjars $ {android.libraryjars} satırlarını kaldırmam gerekiyor mu? Teşekkür ederim! – bursk

+0

Ayrıca yaptığım başka bir şey eklemek için cevabımı değiştirdim. –

+0

Yardımlarınız için teşekkürler. Hala bir şey eksik olmalıyım. Ben proguard.cfg'imi kütüphane kavanozlarını nasıl eklediğimi ve eklediklerimi nasıl eklediğimi gösterecek şekilde düzenledim. (=libraryjars $ {android.libraryjars}) ve (<özellik adı = "android.libraryjars" refid = "android.target.classpath" /> ) satırlarımdan build.xml 'i hedef isminden değiştirdim = " -obfuscate ", ancak ant yayınlamayı denediğimde, libmessaging.jar dosyasında bulunan tüm sınıflar için" sınıf java.lang.String başvurulan sınıfı "ve" kitaplık sınıfının yinelenen tanımını bulamıyorum "gibi hatalar alıyorum. – bursk

3

ProGuard jsoup lib şifrelendiğinde benzer bir sorun yaşadım. Ben onları biliyordu

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