问题
I have created the .aar file (containing the resources & drawables) of an Android library project using
./gradlew assemble
I have enabled obfuscating by setting minify == true
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
However when I run the mentioned gradle command with minify enabled = true, I get java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?
What does this error pointing to and how can I obfuscate the library .aar file?
Best Regards
回答1:
Proguard cuts unused classes. Libraries are standalone products, and has some specific entry points, which should not be obfsuscated. So you need to add rules to keep this entry points. Rules lookes like this:
-keep class packagename {public *;}
回答2:
Using Proguard worked like a charm for me!
Proguard is used to shrink, obfuscate, optimize code. Proguard is necessary for your library to remove unused code and make reverse engineering little difficult. Proguard rules for the library are different from the normal applications. As you know, Proguard renames classes, variables, and methods using meaningless names. You would like to keep the names of those methods and classes as it is that developers will call. You will need to test and verify obfuscated code from generated AAR file.
Library Module build.gradle of your library
buildTypes {
release {
// Enables code shrinking, obfuscation, and optimization for only
// your project's release build type.
minifyEnabled true
// Includes the default ProGuard rules files that are packaged with
// the Android Gradle plugin. To learn more, go to the section about
// R8 configuration files.
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
Inside of your proguard-rules.pro of your library
# Save the obfuscation mapping to a file, so we can de-obfuscate any stack
# traces later on. Keep a fixed source file attribute and all line number
# tables to get line numbers in the stack traces.
# You can comment this out if you're not interested in stack traces.
-printmapping out.map
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,EnclosingMethod
# Preserve all annotations.
-keepattributes *Annotation*
# Preserve all public classes, and their public and protected fields and
# methods.
-keep public class * {
public protected *;
}
# Preserve all .class method names.
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
# Preserve the special static methods that are required in all enumeration
# classes.
-keepclassmembers class * extends java.lang.Enum {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
# You can comment this out if your library doesn't use serialization.
# If your code contains serializable classes that have to be backward
# compatible, please refer to the manual.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# The library may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
# -keep public class mypackage.MyClass
# -keep public interface mypackage.MyInterface
# -keep public class * implements mypackage.MyInterface
Thanks to .... reference
https://dev.to/mohitrajput987/develop--publish-your-own-sdk-in-android---part-2getting-started-with-sdk-development-3159
回答3:
Two suggestions:
- Please ensure this file exist in the library module: proguard-rules.pro.
- Please try running "./gradlew :mylib:assembleRelease" with the "mylib" be replaced with your library module name.
回答4:
- Copy library.pro file to your library project from this location:
...\android-sdk\tools\proguard\examples
- Comment these lines when building from Android Studio, it should be probably kept/updated when building from the command line:
-injars in.jar -outjars out.jar -libraryjars /lib/rt.jar
Update your library project
build.gradle
file to uselibrary.pro
:release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro' }
Sync and build the project and it should generate an obfuscated AAR file now.
来源:https://stackoverflow.com/questions/29365161/obfuscating-the-aar-files