How to minify a Flutter app with Proguard?
Asked Answered
T

5

32

I already made a Flutter app. The release apk is about 14MB. I searched methods to minify this and found this ons: https://flutter.io/android-release/#enabling-proguard

But my question is, how can I get to know all my used additional libraries for step 1? Are there any commands to know them or is it just all the dependencies that I added to the pubspec.yaml ?

How do I need to implement them in this file /android/app/proguard-rules.pro?

Technical answered 20/9, 2018 at 15:55 Comment(5)
I doubt pro guard will do much. Dart compile use tree shaking already. So unless you code directly in Java (which is unlikely), the win is minimal. Maybe that size comes from your assets.Uninspired
That's possible, but at least I could give it a try if I know what rules I need to add to the proguard-rules.pro file.Technical
Possible duplicate of Flutter apps are too big in sizeChamplain
medium.com/@swav.kulinski/…Permanent
Did you find the answer for your question ? If yes, please share the answer.Corsica
U
62

First, we will enable shrinking and obfuscation in the build file. Find build.gradle file which sits inside /android/app/ folder and add lines in bold

android {

    ...

    buildTypes {
        release {
            signingConfig signingConfigs.debug     

            minifyEnabled true
            useProguard true

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 

        }
    }
}

Next we will create a configuration which will preserve entire Flutter wrapper code. Create /android/app/proguard-rules.pro file and insert inside:

#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }

Note: Use signingConfigs.release instead signingConfigs.debug to build a apk or appbundle

Ulloa answered 5/12, 2019 at 19:23 Comment(2)
don't use this line for release apk--> signingConfig signingConfigs.debug use --> signingConfig signingConfigs.releaseRetire
Any update on proguard for flutter wrapper code? Where do I find these default proguard lines?Argument
B
32

I will leave this answer here as an addition for any poor soul that has to deal with this issue and encounters this thread.

As of December 2021 with the latest Android Sdk, Studio and Flutter versions, if you try to douseProguard true it will not work because it's obsolete. Sadly, Gradle will not tell you this, instead, you will get an error like this:

A problem occurred evaluating project ':app'.

> No signature of method: build_7cqkbrda1q788z3b02yxbvrx9.android() is applicable for argument types: (build_7cqkbrda1q788z3b02yxbvrx9$_run_closure2) values: [build_7cqkbrda1q788z3b02yxbvrx9$_run_closure2@41108b15]

Which as you can see it is complete gibberish and not useful. The secret is to just not use useProguard at all. By default Flutter is setup to use R8 which handles minification now on Android.

Here is a so post about this for reference: Gradle : DSL element 'useProguard' is obsolete and will be removed soon

Bimonthly answered 8/12, 2021 at 1:19 Comment(2)
Been struggling on this for an hour now.Alanna
You are n live safer. I still have one question: When I publish my app to play store it sill warns me that proguard is missing. Is this normal?Humanize
M
6

Latest Solution

At first you should use shrinkResources true instead of useProguard true in android/app/build.gradle.

In second instead of using proguard-android.txt you should use proguard-android-optimize.txt.

[Update] Attention: If you don't want to optimize, use the proguard-android.txt configuration file instead of this one, which turns off the optimization flags. Adding optimization introduces certain risks, since for example not all optimizations performed by ProGuard works on all versions of Dalvik. To check how to turn off various optimization you need to read more at official Google Proguard reference.

buildTypes {
              
    release {
         signingConfig signingConfigs.release

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

Following is newer version of proguard configuration rules to prevent logging and other retrofit protection:

# Flutter
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }

# Retrofit
-keepattributes Signature
-keepattributes Exceptions

# OkHTTP
-dontwarn okhttp3.**
-keep class okhttp3.**{ *; }
-keep interface okhttp3.**{ *; }

# Other
-keepattributes *Annotation*
-keepattributes SourceFile, LineNumberTable

# Logging 
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
    public static *** wtf(...);
}

-assumenosideeffects class io.flutter.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** w(...);
    public static *** e(...);
}

-assumenosideeffects class java.util.logging.Level {
    public static *** w(...);
    public static *** d(...);
    public static *** v(...);
}

-assumenosideeffects class java.util.logging.Logger {
    public static *** w(...);
    public static *** d(...);
    public static *** v(...);
}

# Removes third parties logging
-assumenosideeffects class org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
    public *** info(...);
    public *** warn(...);
    public *** error(...);
}

To check it, install jadx and open your_app.apk and search inside of that about log. You should have comparison between non-proguard .apk and proguard configured .apk log search result.

Without Proguard rules

Before proguard configuration rules

With Proguard rules

After config rules

Read more in official Android documentations.

Read more about Android code shrink.

Malines answered 25/9, 2023 at 7:42 Comment(3)
Careful with proguard-android-optimize.txt, as it will turn on some potentially dangerous optimizations. Read more here: #56902856Thaler
@Thaler Based on official Android shrink and obfuscate, R8 ignores any ProGuard rules that attempt to modify default optimizations, such as -optimizations and -optimizationpasses flags. If you think R8 is difference with this hypothesis, I will edit and update my answer. ThanksMalines
Well there's a difference depending on the file name you use, see: android.googlesource.com/platform/sdk/+/master/files/…Thaler
G
2

If you are using firebase, see Flutter build crashes using ProGuard with Firebase Auth

Next, you need to consider the dependencies in pubspec.yaml You can immediately ignore any pure Dart packages - you are just looking for plugins. Of these plugins, you are just interested in ones that make use of existing libraries. You will likely have added these to gradle. Those are the ones you need to protect from name shortening.

The simplest approach may just be to try it and see what package names pop up in the NoClassDefFoundError and keep iteratively adding them.

As Remi says, your gain will be minimal, so is it really worth the hassle. You should see some improvements in APK sizes over the coming releases.

Gentlemanatarms answered 20/9, 2018 at 16:40 Comment(0)
S
0

By default flutter enable it on command flutter build at least on version 3.19.x

References

Slaughterhouse answered 18/3 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.