Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obfuscating multiple modules with android studio

I am having problems with gradle proguard... I have the following modules:

  • App :main app module. Have dependency ModuleA and ModuleC
  • ModuleA: library module. Have dependency ModuleB, and jar dependecies.
  • ModuleB: Library module
  • ModuleC: library module
  • Wear: wear app module.

build.gradle files: - App:

buildTypes {
       release {
           minifyEnabled true
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
 }
dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   compile project(':ModuleA')
   compile project(':ModuleC')
   wearApp project(':Wear')
}

ModuleA:

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile project(':ModuleB')
}

ModuleB:

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

ModuleC: The same as ModuleB.

Wear:

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

**I wrote only the important lines

My problem is that if I generate a signed APK with that configuration, when I install it on a device it crashes with this exception:

java.lang.NoSuchFieldError: no field with name='peer' signature='J' in class Lcom/package/ClassInJar;

It crashes in a class contained in a jar in the libs folder of module A.

If I set minifyEnabled to false in all modules it doesn't crash, but I prefer to obfuscate the code. And if I turn minifyEnabled to true in library modules it doesn't compile and it shows me this exception:

Error:Execution failed for task ':ModuleB:proguardRelease'.

java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?

like image 941
RoberV Avatar asked Feb 05 '15 11:02

RoberV


People also ask

How do I obfuscate my library on Android?

In order to obfuscate your library what you need to do is: Make sure gradle settings for lib module state minifyEnabled true . run ./gradlew assemble{flavor}Release.

What is multi module in Android?

A project with multiple Gradle modules is known as a multi-module project.

What is the difference between ProGuard and R8?

R8 has more Kotlin support than that of Proguard. R8 is having a faster processing time than Proguard which reduces build time. R8 gives better output results than Proguard. R8 reduces the app size by 10 % whereas Proguard reduces app size by 8.5 %.

Is ProGuard deprecated?

No. You can use obfuscation and optimization tooling.


1 Answers

First it is important to understand that proguard plays two main rolls:

  • When proguard obfuscate it actually takes all of your classes, classes members, methods etc and changes their names so it will become gibberish. That way it makes it a lot harder for someone to reverse-engineer your code.
  • It shrinks the code in a way so that every unused class, class member, method etc is discarded at compile to make your apk slimmer.

So as far as "minify" goes, it is not necessary, even though it might save you a few kilobytes here and there. You can probably leave it off and it will be fine.

As for the crash - this happens because a part of your code is trying to reach a class which it's name probably got obfuscated and therefor missing.
Try setting rules for the proguard. that could be done like so:

  • Locate the 'proguard-rules.pro' file which is located just next to the 'build.gradle' file inside the "app" folder (image below).enter image description here

  • Next you need to add 'keep' rules for the specific classes/class members/ methods/ etc so that the obfuscation won't occur on these elements. You have examples commented out within the file, for example:

    -keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; }


Which means "don't obfuscate any class members which are public within the given class.

But, there are many variations of the keep.
For more information on 'keep' variations check this documentation with examples (when you click an item) in the link: Keep options.

Good luck =)

like image 191
Shahar.bm Avatar answered Oct 16 '22 13:10

Shahar.bm