Android obfuscate приложение с помощью proguard поддерживает обфускацию библиотечных банок – или это так?

Я новичок в использовании Proguard, поэтому я, вероятно, ошибаюсь. У меня есть приложение, которое после запуска сборки релиза (который использует Proguard для обфускации), он быстро падает. Я считаю, что я сузил его до того, что кажется, что он запутывает мои справочные библиотеки. В моем случае мои справочные библиотеки используются для определения моих классов сообщений, которые я использую для связи с другим устройством с помощью Google Protobuffers. Я использую, ant релиз. Моя конфигурация proguard:

-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> к <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, чтобы запутать библиотечные банки или у меня что-то 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]... 

Благодаря!

Solutions Collecting From Web of "Android obfuscate приложение с помощью proguard поддерживает обфускацию библиотечных банок – или это так?"

Вы прокомментировали свои директивы jar библиотеки в конфигурации Proguard.
Изменить:

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

чтобы:

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

(А затем не мешайте определять свои библиотеки в вашем файле build.xml)

РЕДАКТИРОВАТЬ:
Я нашел другой способ сделать баннеры библиотеки Proguard в одиночку – попросить его сохранить свои имена пакетов, например:

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

У меня была аналогичная проблема, когда proGuard зашифровал jsoup lib. Я исправил это, добавив следующее к моему proguard-rules.txt :

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

Итак, build.gradle закончится следующим разделом:

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