Flutter --obfuscate vs R8 minifyEnabled true

210 Views Asked by At

Flutter has an option to obfuscate a release build using --obfuscate, for example:

flutter build apk --obfuscate

I can also enable R8 obfuscation in the Android runner part of my Flutter app via the android/app/build.gradle:

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

According to the Flutter FAQ, this is what happens when I build my apk:

The engine’s C and C++ code are compiled with Android’s NDK. The Dart code (both the SDK’s and yours) are ahead-of-time (AOT) compiled into native, ARM, and x86 libraries. Those libraries are included in a “runner” Android project, and the whole thing is built into an .apk. When launched, the app loads the Flutter library.

I don't understand this deeply, but it suggests that if Flutter is obfuscating the app, and including it as a library, then the --obfuscate flag make the R8 obfuscation redundant - is that right?

  • and vice versa, if I have minifyEnabled true does that make --obfuscate redundant?
  • or do they do different things - if yes, how are they different?
  • should I use both?
1

There are 1 best solutions below

0
On

Flutter apps are fundamentally android apps, which use the gradle build system. The gradle rules for flutter apps are using a flutter-specific gradle plugin which handles flutter specifics.

  • The Java/Kotlin code is compiled & bundled by the normal android gradle rules. The configuration of it is therefore in those android gradle rules, including the one you pointed at android/app/build.gradle which configures options to R8 (which compiles, optimizes and bundles the Java/Kotlin code). The resulting app.apk will have the compiled Java/Kotlin code in the form of .dex files in it.

    => The flutter-specific gradle plugin currently modifies those R8 options internally and therefore applies to all flutter apps. There's an open issue about this, because it applies proguard rules that prevent proper optimization, see https://github.com/flutter/flutter/issues/136879

  • The main part of flutter apps is written in Dart. This Dart code will be AOT compiled to an ELF file (the app.apk will contain a libapp.so). The flutter --obfuscate flag means that the Dart code in that ELF file will be obfuscated.

    => The obfuscation of Dart code works as expected. You may want to also consider using --split-debug-info (see https://docs.flutter.dev/deployment/obfuscate) that leads to smaller apps with less symbols in them (as symbols are split into a separate file)