121

I have created android build of my Flutter application.

Then I created an internal testing release. It is showing a warning

This App Bundle contains native code, and you've not uploaded debug symbols. We recommend you upload a symbol file to make your crashes and ANRs easier to analyze and debug.

Basically what I had to do is add following to build.gradle file according to the link they show.

android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }

I assume it is android/app/build.gradle they are talking about.

Not sure exactly where in that file I have to add this line.

Can someone point out where to add this line?

Janaka
  • 2,505
  • 4
  • 33
  • 57

4 Answers4

152

To use the option ndk debugSymbolLevel as written in the docs you need an android gradle plugin 4.1 or later. At the time of writing the lastest 4.1 version is 4.1.2

You will need also to install ndk and cmake for android studio.

In your android build.gradle you need the to set android gradle plugin version 4.1.2:

buildscript {
    ...
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.2'
        ...
    }

Then in the android/app build.gradle add:

...
android {
    ...
    // you see the ndk version in the android studio sdk-manager
    // have a look also here: https://stackoverflow.com/a/65747847/9481613
    ndkVersion "21.3.6528147" 
    ...
    buildTypes {
        release {
            ...
            ndk {
                debugSymbolLevel 'SYMBOL_TABLE'
            }
        }   
    }
}

when you then run: flutter build appbundle it should finish after a while with an appbundle that is twice the size.

Adam
  • 2,800
  • 1
  • 13
  • 15
  • 2
    Minimum `gradle-6.6.1-all.zip` in `gradle-wrapper.properties` required for latest gradle `(4.2.0-alpha12')` plugin – Pratik Butani Sep 25 '20 at 05:22
  • 3
    gradle-6.5 is the minimum. Just change the plugin version: classpath 'com.android.tools.build:gradle:4.1.0' in the top level gradle file. This will prompt to fix gradle and will install 6.5. Keep in mind, this required android studio version 4.1 or higher. – user3508953 Oct 16 '20 at 04:25
  • 1
    Amazing, thank you! Question: why choose `'SYMBOL_TABLE'` over `'FULL'` ? – pierrea Oct 23 '20 at 17:35
  • 1
    Hi @pierrea, both attributes are described in the first link of the answer. Bascially its how much debug information you want to include: `Note: There is a 300 MB limit for the native debug symbols file. If your debug symbols footprint is too large, use SYMBOL_TABLE instead of FULL to decrease the file size.` – Adam Oct 25 '20 at 09:39
  • Do you know if this configuration option does also pick up **unstripped** debug symbols packaged in a **library *.aar** which is downloaded as a Maven artifact? – JJD Feb 03 '21 at 14:52
  • 3
    If the appbundle is twice the size, does the app on the play store also doubles the size? – kyu May 12 '21 at 07:13
  • Would make sense to me. You can also run `flutter build appbundle --analyze-size` to see what is inside. Typically you would add debug information to you build for beta testing but not in a production release. – Adam May 13 '21 at 10:38
  • this answer shows how to use the menu to get the ndk version number: https://stackoverflow.com/a/65747847/9481613 – mLstudent33 Sep 27 '21 at 23:41
  • Hi @mLstudent33, thanks for the input. I had that previously in the comment but just see I put a bash style comment before. I fixed that and added your link to show ndk version in android studio sdk-manager – Adam Sep 30 '21 at 14:43
  • Do you still need to pass the --obfuscate --split-debug-info flags for the ofuscation to take place? – Bugzilla Nov 27 '21 at 12:06
  • Hi @Bugzilla, I think yes. For flutter 2.5.3 running the help `flutter build appbundle -h` shows: "In a release build, this flag removes identifiers and replaces them with randomized values for the purposes of source code obfuscation. This flag must always be combined with "--split-debug-info" option, the mapping between the values and the original identifiers is stored in the symbol map created in the specified directory. For an app built with this flag, the "flutter symbolize" command with the right program symbol file is required to obtain a human readable stack trace." – Adam Dec 02 '21 at 23:07
  • 1
    Still does not work for me :D. Don't know why. And I still see `Task :app:stripReleaseDebugSymbols` in the output of `flutter build appbundle -v` – vietstone Dec 09 '21 at 08:47
  • 1
    as 2023, now gradle version is 7.1.2, it's not working. It's working only gradle version 4.1.x, I think. check out https://github.com/flutter/flutter/issues/98773 – 9Dragons May 23 '23 at 07:24
49

There's two places in the app/build.gradle where you can specify bundling of debugging symbols with your app. If you use android.defaultConfig.ndk.debugSymbolLevel it will apply it to all build types (i.e., both debug and release builds). On the other hand, if you use android.buildTypes.release.ndk.debugSymbolLevel it will apply only to your release build.

These options have to be added into your app/build.gradle file as you correctly guessed. When you see a build property that's in this dotted notation, it actually corresponds to nested blocks in the build.gradle, which would look a bit like this:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId 'com.example.foo'
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 42
        versionName "4.0.2"
        ndk {
            debugSymbolLevel 'SYMBOL_TABLE'
        }
    }
    // Rest of the file
}

HTH

Alberto
  • 925
  • 6
  • 4
  • 6
    Where I can find a file to upload on playstore ? – Web.11 Feb 06 '21 at 12:49
  • 1
    Read here https://developer.android.com/studio/build/shrink-code#native-crash-support – Davide Bicego Mar 02 '21 at 17:05
  • 3
    Native debug symbols are included in app bundle, but if you use apk they are located here: app/build/outputs/native-debug-symbols/variant-name/native-debug-symbols.zip – Zoran Jul 08 '21 at 11:03
  • 1
    Is it **meaningless** to add symbol files to an **obfuscating** bundle? On one hand I want to difficult reverse engineer, on the other hand I want to be able to read my stackTrace (I'm using firebase crashalytics) @Alberto – genericUser Nov 07 '21 at 11:13
  • 2
    That's not a problem. The proguard mappings and unstripped libraries are never sent to users when they install your app so there's no reverse engineering possible. It is all securely stored in Play Console and used for the crash reporting features. – Alberto Nov 07 '21 at 15:58
  • Do I have to add the line ndkVersion "21.3.6528147" somewhere? If so, where? – Ton Feb 18 '22 at 10:50
  • 1
    To upload on store, mapping dSYM file can be found in `android/app/build/outputs/mapping/release/mapping.txt` – Hamza Waleed Apr 05 '22 at 17:16
  • for thoese who can't find the files, check out https://stackoverflow.com/a/68778908/3786285 – MartianMartian Oct 21 '22 at 04:14
2

Use Android Version 4.1 and above currently 4.1 RC 3 and 4.2 Canary 13 is available, and similarly use com.android.tools.build:gradle 4.1 and above, you can search for the suitable version from here

Then use this line in android -> defaultConfig in your app build.gradle file

    ndk { debugSymbolLevel 'FULL' }
Sid.The.Biker
  • 300
  • 2
  • 13
1

If none of solutions work, you can also create a Sample JNI Application from Android Studio's project templates. Build it and check whether it got built successfully and installed on a device.

I have inspected its app build.gradle file and compared my Flutter's build.gradle. So I added this to make it work:

defaultConfig {

    // append below:
    externalNativeBuild {
            cmake {
                cppFlags "-std=c++17"
            }
        }
}

Michał Dobi Dobrzański
  • 1,449
  • 1
  • 20
  • 19