Android Crashlytics ndk; values of NdkOut and NdkLibsOut in build.gradle - android

I have integrated Crashlytics, Fabric into my app, the sdk related crashes are reported successfully.
For the ndk part, i have followed instructions from the blog; The Wait is Over: Launching Crashlytics for Android NDK, but the ndk crashes aren't being reported. My doubt is, because other parts are sufficiently clear, i'm not providing the correct path for androidNdkOut and androidNdkLibsOut, as shown in:
The doubt and question is in my build.gradle, here it is...
crashlytics {
enableNdk true
androidNdkOut //what would be the obj here?
androidNdkLibsOut 'src/main/jniLibs' //path for my jni libraries
}
please let me know if i should post any other part of the code

EDIT/UPDATE July 7, 2017
Matt from the Fabric team here with an update to this answer - we just released the Fabric Gradle plugin version 1.23.0 which includes support for automatically detecting the appropriate native library paths when you're using the externalNativeBuild DSL with the Android plugin for Gradle version 2.2.0+, so you no longer need to set the androidNdkOut and androidNdkLibsOut properties. This will work with both CMake and ndk-build. Check out more info here: https://docs.fabric.io/android/crashlytics/ndk.html#specifying-the-path-to-debug-and-release-binaries
I could solve the problem after getting help from Crashlytics/Fabric Support, thanking them..this answer.
First, for
crashlytics {
enableNdk true
androidNdkOut //what would be the obj here?
androidNdkLibsOut 'src/main/jniLibs' //path for my jni libraries
}
for my app's build.gradle, it should have been:
crashlytics {
enableNdk true
androidNdkOut 'src/main/jniLibs'
androidNdkLibsOut 'src/main/jniLibs'
}
androidNdkOut is where your debug binaries are located. This defaults
to 'src/main/obj' but you can set in the crashlytics { } if it's
different in your project.
a link which contains useful information on the same: crashlytics knowledgebase; Missing line numbers in native crashes
A minor but very useful part was running commands like uploadReleaseSymbols with the --stacktrace option. Thought its worth the mention as that(uploading release symbols) was also an issue on my side for not receiving the crash reports.

Follow this guide -https://fabric.io/downloads/gradle/ndk. We kept empty both fields (androidNdkOut and NdkLibsOut)

Had a similar problem: I had to add CrashlyticsNdk kit at Fabric.with().
Fabric fabric = new Fabric.Builder(context)
.kits(new Twitter(authConfig), new Crashlytics(), new CrashlyticsNdk())
.debuggable(true)
.build();
Fabric.with(fabric);
you can check androidNdkOut, androidNdkLibsOut this way.
$ ./gradlew -d clean assemble{Flavor} | grep ndk-build
and you will find NDK_OUT and NDK_LIBS_OUT.

Related

What does 'minifyEnabled=true' do when all configuration options are disabled?

I have a complicated build setup for an android app which basically consists of a normal android app fused together with a Xamarin/Mono project in order to include an important C# library (like this: https://github.com/royd/KotlinAppWithXamarinDependency)
Everything is working fine except if I enable minification in my app/build.gradle via minifyEnabled true the app instantly crashes on startup because the Mono-runtime can't find native assemblies that are definitely contained in the apk.
This is the message I get in Logcat:
A/monodroid: No assemblies found in '(null)' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...
With minifyEnabled false everything is working fine so I tried disabling all config options in my proguard-rules.pro:
-dontobfuscate
-dontoptimize
-dontshrink
And I also added the following lines to my app/build.gradle
packagingOptions {
doNotStrip "*/armeabi/*.so"
doNotStrip "*/armeabi-v7a/*.so"
doNotStrip "*/x86/*.so"
}
Unfortunately all this doesn't help.
I also decompiled a working and a broken apk with dex2jar to compare the bytecode. It seems to be exactly the same except for some enum-optimizations that shouldn't matter.
According to the error message in Logcat the error seems to be thrown from the native library libmonodroid.so.
So my question: What does minifyenabled flag do when all these config options are disabled?
Edit:
I have found out that minification works as intended when I use version 4.0.1 of Android Gradle Plugin (from July 2020). Upgrading the version to 4.1.0 (August 2020) breaks my app. Now the question is what changed between these two versions?
When you set the minifyenabled as true. The r8 will choose the configuration files but not only the proguard-rules.pro and the app/build.gradle to shrink, obfuscate, and optimize your app.
There are some others files such as AAR libraries: <library-dir>/proguard.txt and
JAR libraries: <library-dir>/META-INF/proguard/ and so on. So this error may be caused by the native library losing when you set the set the minifyenabled as true.
If you need more information, please check the official document:https://developer.android.com/studio/build/shrink-code#enable
In addition, you can check the 'proguard-android-optimize.txt' and when you add the -dontoptimize to proguard-rules.pro may cause a conflict.
I found out, that in the Android Gradle Plugin versions 3.6.0 to 4.1.0 they switched to a more performant tool for building apks called zipflinger.
This tool can be disabled by adding this line to my gradle.properties:
android.useNewApkCreator=false
When building the apk zipflinger stores the external .NET assemblies as DEFLATED zip entries instead of STORED and thats why monodroid cant read them.
References:
https://github.com/xamarin/xamarin-android/issues/6838#issuecomment-1110816027
https://copyfuture.com/blogs-details/20210119115509664T

Error when executing crashlyticsGenerateSymbols task with android gradle plugin 3.6+

Where do i report this error? or could anyone help me?
“Directory X specified for property ‘$2’ does not exist” error when executing crashlyticsGenerateSymbols task
with
android gradle plugin 3.6.0
gradle version 5.6.4
fabric gradle plugin 1.31.2
[Error logs]
Some problems were found with the configuration of task ':~~~~~:crashlyticsGenerateSymbolsRelease' (type 'DefaultTask').
Directory '~~~' specified for property '$1' does not exist.
Directory '~~~~' specified for property '$2' does not exist.
Fabric/Firebaser here. This error comes up when the Fabric Gradle plugin is trying to parse your project structure in order to find your stripped and unstripped binaries, and is unable to do so. When it asks for properties $1 and $2 it means it could not find the default paths to the "obj" and "libs" folders that contain your supported ABIs folders with your supported native libraries there.
Using the legacy Fabric Gradle plugin, you can specify these paths under your crashlytics block in the build.gradle, like so:
crashlytics {
enableNdk true
androidNdkOut 'obj'
androidNdkLibsOut 'libs'
}
In the case for builds that are on Android Studio 3.5 or later, you can usually find the paths for these somewhere in the outputted build folders under "merged_native_libs" and "stripped_native_libs."
If you're using the new Firebase Crashlytics SDKs and Gradle plugin, those paths are controlled by "strippedNativeLibsDir" and "unstrippedNativeLibsDir" flags in the firebaseCrashlytics block in your build.gradle.
If you continue running into problems feel free to file a case with Firebase support with more details about your project and what you've tried to configure so far, and you can also still reach out to support#fabric.io.
I got the same issue on my side, and I fixed it by removing ext.enableCrashlytics = false from my app-level build.gradle in
android {
buildTypes {
debug {
// ext.enableCrashlytics = false
}
}
}

Crashlytics Android NDK: missing all symbols in crash reports

Our native Crashlytics crash reports are missing all symbol information as of late. I had hoped that the latest Crashlytics NDK would resolve the issue, but it does not.
I see that there is a similar query out there, but in this case I am not using Firebase, just Crashlytics, and had been doing so successfully for quite some time.
Our build.gradle (using CMake and the Gradle 3.0.0 or 3.1.0 Android plugin -- same issue either way) contains:
buildscript {
...
dependencies {
...
classpath 'io.fabric.tools:gradle:1.+'
}
}
...
dependencies {
...
implementation('com.crashlytics.sdk.android:crashlytics:2.9.1#aar') {
transitive = true
}
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.0.2'
}
Which would seem to be correct and using all the latest Fabric components unless I am missing something.
I then added:
crashlytics {
enableNdk true
manifestPath 'AndroidManifest.xml'
}
tasks.whenTaskAdded { task ->
if (task.name.startsWith('assemble')) {
task.finalizedBy "crashlyticsUploadSymbols" + task.name.substring('assemble'.length())
}
}
none of which I had needed some time ago when this was working. (And, no, just adding the crashlytics block was insufficient.)
This gives me symbols for the .cpp files I actually build in this project. It still has no symbols for the .a file I link in, nor even for libc++_shared.so!
For Java
https://docs.fabric.io/android/crashlytics/dex-and-proguard.html
Configure ProGuard and DexGuard
We’ve made it simple to set up ProGuard or DexGuard in your app and receive deobfuscated crash reports. First of all, Fabric uses annotations internally, so add the following line to your configuration file:
-keepattributes *Annotation*
Next, in order to provide the most meaningful crash reports, add the following line to your configuration file:
-keepattributes SourceFile,LineNumberTable
Crashlytics will still function without this rule, but your crash reports will not include proper file names or line numbers.
For C++
https://docs.fabric.io/android/crashlytics/ndk.html
Specifying the path to debug and release binaries
To properly symbolicate and process native crashes, we need the symbols from your native binaries. Typically, Android’s native binary build processes produce two sets of binaries: one set with debugging symbols, and one set to be packaged in your final APK. The Fabric plugin uses both sets of binaries to generate a symbol file on your machine. The symbol generation and upload process assumes your project will have two directories - one for the debug binaries (called obj below), and one for the release binaries (called libs below) - that are broken down by architecture-specific folders.
When building your project with the Android plugin for Gradle version 2.2.0+ with the externalNativeBuild DSL, the Fabric plugin is able to automatically detect the necessary directories for each native build variant in order to generate the appropriate symbol files.
obj/
— armeabi
+ lib1.so
+ lib2.so
— x86
+ lib1.so
+ lib2.so
libs/
— armeabi
+ lib1.so
+ lib2.so
— x86
+ lib1.so
+ lib2.so
The paths to the debug and release binaries can be manually controlled via the androidNdkOut (default: src/main/obj) and androidNdkLibsOut (default: src/main/libs) properties. Ant users can modify these in the fabric.properties file. Gradle users can control these via the crashlytics {} block in their build.gradle.
Ant: ant crashlytics-upload-symbols
Gradle: ./gradlew crashlyticsUploadSymbols{Variant}
For example: ./gradlew crashlyticsUploadSymbolsRelease
You should also read "Uploading symbols for external dependencies" it it applies to your code.
add the following to your gradle.properties file:
android.bundle.enableUncompressedNativeLibs = false

Crashlytics NDK for external subproject dependency

I'm trying to implement Crashlytics for my project which uses NDK/JNI. However the JNI part is in a project loaded externally like this in settings.gradle:
include ':app', ':core'
project (':core').projectDir = new File(rootDir, '../core')
I read that for some time Crashlytics should find the symbols automatically without the need to specify androidNdkOut and androidNdkLibsOut. It didn't work for my scenario, when I called ./gradlew crashlyticsUploadSymbols{flavor}Debug it complained about wrong androidNdkOut.
So I added those paths explicitly in the app's build.gradle:
crashlytics {
enableNdk true
androidNdkOut '../../core/build/intermediates/cmake/debug/obj'
androidNdkLibsOut '../../core/build/intermediates/cmake/release/obj'
manifestPath 'src/main/AndroidManifest.xml'
}
Crashlytics does find them right now and the crashlyticsUploadSymbols{flavor}Debug returns success. But it doesn't work properly. Some of the errors are not reported at all in the Crashlytics console, the rest is not deobfuscated. Also Crashlytics shows something like this in the logcat:
W/CrashlyticsCore: No minidump data found in directory /data/data/com.example.app/files/.Fabric/com.crashlytics.sdk.android.crashlytics-ndk/native/1513601249792
What should I do for my configuration to properly log the NDK exceptions in Crashlytics console?
Configuration that you specified in build.gradle is not correct.
androidNdkOut should point to object files, something like '../../core/build/intermediates/cmake/release/obj'
androidNdkLibsOut should point to actual libraries. in your case, most probably '../../core/build/intermediates/transforms/mergeJniLibs/release/folders/2000/3/main/lib'

Android gradle, about those methods that are deprected after updating

I have encountered this problem several time whenever I update my Gradle version & Gradle Android plugin. For example, I used to use:
Gradle 2.1
Gradle Android Plugin com.android.tools.build:gradle:0.13.3
With this version, my build script contains for example:
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), \
'proguard.cfg'
}
debug {
runProguard false
}
}
Few weeks later, I saw a new Gradle version (2.2.1) was released, so, I updated my Gradle & Gradle Android Plugin to newer version:
Gradle 2.2.1
Gradle Android Plugin com.android.tools.build:gradle:1.0.0+
Then, I run command gradle clean build, suddenly, the build is not successful anymore, because with the newer version, I got error:
Could not find method runProguard()
My questions are:
(MAIN QUESTION) It seems everytime when the Gradle & Gradle Android Plugin are updated, there are always some methods are deprecated, it is understandable. BUT, I am really appreciate if there is a document summarizes all the deprecated methods & their replacements. So, where can I find such information? Seems Gradle & Gradle Android Plugin don't do a good job on this to facilitate developers to quickly migrate the build script to newer version.
How to get rid of the error: Could not find method runProguard() in my above case?
change
runProguard ****
to
minifyEnabled ****
you can get the deprecated methods or resources here http://tools.android.com/tech-docs/new-build-system for the android studio builds or releases
I really want to know where is the place to find out the replacements of deprecated methods in general when Gradle & Gradle Android Plugin are updated
That would be the documentation, particularly the release notes. 0.14.0 renamed runProguard to minifyEnabled, and 0.14.3 removed runProguard.
You should replace runProguard true with minifyEnabled true, there are a lot of question about this topic.
On your first question, I read some official statement here saying that, from now on, they'll try to stick to actual methods name and/or provide support info, to make the switch between gradle versions easier, so you shouldn't be worried.
From version 1.0.0 and going forward, we will strive much harder to not make incompatible changes, and if we do, we plan to write IDE support to help migrate the projects automatically.

Categories

Resources