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?
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 resultingapp.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 alibapp.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)