How does android.unitTests.returnDefaultValues work? - android

I know what having the following in an Android project's build.gradle is supposed to do. But how does it work? And what exactly are the default values returned? How do they compare with "real" values?
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}

Per the documentation (emphasis added):
If the exceptions thrown by Android APIs in the android.jar are problematic for your tests, you can change the behavior so that methods instead return either null or zero by adding the following configuration in your project's top-level build.gradle file:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}
}
Caution: Setting the returnDefaultValues property to true should be done with care. The null/zero return values can introduce regressions in your tests, which are hard to debug and might allow failing tests to pass. Only use it as a last resort.

Related

Compile C++ program on Android: undefined function assert

I'm trying to compile my C++ program on Android but it won't compile because assert is undefined.
I've found a couple of hints online but none of them have worked:
I have set APP_OPTIM=debug in myApplication.mk
I have set NDK_DEBUG=1 through parameters override, e.g.
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG:=1"
}
}
I have set the android:debuggable="true" attribute in my Android manifest document.
I have set the build types and toggled debuggable to true and false
buildTypes {
release {
debuggable true
...
}
debug {
debuggable true
...
}
}
I don't know what else I can do. Assert is still being undefined. I must #define assert ; an empty statement to compile. I want to do it the right way.
I am also using CMake and able to use assert.
I would suggest you to try creating new project from android-studio 'File->new project->Choose your project(scroll down and select Native C++)->Next->Next-Finish'. This will create android app with native component in it. modify the .cpp file of native component to use assert(include assert.h) and see if it works.
Also check if this post help you to resolve your issue.
https://stackoverflow.com/a/9144080/4181904

Android and the Fabric (Crashlytics) plugin always generates a UUID (Gradle Kotlin DSL)

I want Fabric to stop generating a UUID on each build. What used to work with Gradle's Groovy DSL does not work with the newer Kotlin DSL. How can I achieve my goal with the Kotlin DSL?
(Gradle version 4.10.2, Fabric 1.25.4)
According to Fabric's documentation, you can add the following to your app's build script
android {
buildTypes {
debug {
// Only use this flag on builds you don't proguard or upload
// to beta-by-crashlytics
ext.alwaysUpdateBuildId = false
and this works. It prevents Fabric from generating a UUID on each debug build. However, if I convert my build script to Kotlin DSL, the following doesn't work
android {
buildTypes {
getByName("debug") {
// Only use this flag on builds you don't proguard or upload
// to beta-by-crashlytics
ext.set("alwaysUpdateBuildId", false)
Fabric ignores this value, now.
I have tried variations, such as the following:
project.ext.set("alwaysUpdateBuildId", false)
rootProject.ext.set("alwaysUpdateBuildId", false)
val alwaysUpdateBuildId by extra(false)
val alwaysUpdateBuildId by project.extra(false)
val alwaysUpdateBuildId by rootProject.extra(false)
None work.
For further reference, the Gradle task generating this value appears to be named :app:fabricGenerateResourcesDebug, and has type DefaultTask.
As Martin Rajniak mentioned, you can only call extra on ExtensionAware objects, with BuildType not being declared as one.
However, during runtime, build types actually are ExtensionAware, which is why this works in Groovy due to its dynamicity, but not in Kotlin where extra in this scope will reference the Project's extensions.
In order to achieve this without Groovy, we can simply cast the build type to ExtensionAware:
android {
buildTypes {
getByName("debug") {
(this as ExtensionAware).extra["alwaysUpdateBuildId"] = false
}
}
}
I have found a workaround to this problem. Create a file, fabric.gradle (Groovy build script!) and place it in your project structure somewhere. It will have the following contents:
// or "com.android.library"
project.pluginManager.withPlugin("com.android.application") {
android.buildTypes.debug.ext.alwaysUpdateBuildId = false
}
Now, in the build script for your module (let's call it app/build.gradle.kts), apply this script plugin:
apply(from = "path/to/fabric.gradle")
This workaround is based on the advice here, in the Kotlin DSL primer.

Android: How to reset resConfigs for release variant?

To make development faster, I want to do the following:
android {
defaultConfig {
resConfigs "en"
}
}
My app has a lot of languages, and doing this saves significant time while developing. However, I do NOT want to release a version with this set. Unfortunately, resConfigs is not available on product flavors or build types, so I can't set it in debug {}, for example.
How can I automatically exclude resConfigs from release variants? I do not want to have to remember comment out that line of code when I'm building for release.
Wouldn't this work?
Detect the debug build, reset the configurations and add your desired debug configuration.
applicationVariants.all { variant ->
if (variant.buildType.name == "debug") {
variant.mergedFlavor.resourceConfigurations.clear()
variant.mergedFlavor.resourceConfigurations.add("en")
}
}
My solution was inspired by this answer to a related question. Here's how you do it:
in app/build.gradle
// Reset `resConfigs` for release
afterEvaluate {
android.applicationVariants.all { variant ->
if (variant.buildType.name.equals('release')) {
variant.mergedFlavor.#mResourceConfiguration = null
}
}
}
This works because mResourceConfiguration is the backing field for resConfigs. Unfortunately, The Android Gradle DSL does not currently expose a method to reset resConfigs, so we're forced to access the field directly using the groovy #<fieldName> syntax. This works, even though mResourceConfiguration is private.
WARNING: this solution is a little fragile, as the Android Gradle build tools team could change the name of that field at any time, since it is not part of the public API.

Android - Connected Tests Results Directory

I have an android project where I run normal unit tests as well as instrumented tests.
Now the thing is that the results of the
unit tests are stored in build/reports/tests (./debug or ./release)
instrumented tests are stored in build/outputs/connected
Is it somehow possible to change the result directory of the instrumented tests to build/reports/tests/connected?
Thank you already!
Found the answer myself, To change the directory for instrumented tests use:
android {
testOptions {
reportDir = "$project.buildDir/reports"
resultsDir = "$project.buildDir/test-results"
}
# Or for lint if needed
lintOptions {
htmlOutput = file("$project.buildDir/reports/lint/LINT-results.html")
xmlOutput = file("$project.buildDir/test-results/lint/LINT-results.xml")
}
}
I believe this would be more reliable:
android {
[...]
testOptions {
if (project.hasProperty("customResultsDir")) {
resultsDir "${customResultsDir}"
}
if (project.hasProperty("customReportDir")) {
reportDir "${customReportDir}"
}
}
}
There is the bonus that it checks if the property is passed before trying to use it (a good practice). But the real interesting part is that this ways you are interpolating a closure instead of a variable - the differences allow further possibilities (check string interpolation and closure interpolation).
On my scenario, only by using the closure did I manage to have the properties to populate at the exact time.

How to access ext variables in Gradle

I am trying to get the variable defined in a 3rd party library (fabric) to do a condition based on whether Crashlytics is enabled or not.
ext.enableCrashlytics = true
http://support.crashlytics.com/knowledgebase/articles/202938-gradle
The variable can be configured in buildTypes or in flavors but I can't find a way to access it elsewhere in my build.gradle
I tried several things without any luck.
allprojects.getProperties().get("enableCrashlytics")
project.enableCrashlytics
project.ext.enableCrashlytics
allProjects.ext.enableCrashlytics
Anyone tried that before? The context I'm trying to do this is to write the fabric.properties file based on if it is enabled or not.
android.applicationVariants.all { variant ->
...
//create fabric.properties
...
}
You can define a property in your top-level build.gradle:
ext {
myproperty = 12
}
Or an array:
ext {
myarray = [
name0 : "xx",
name1 : "xx"
]
}
Then in each module you can use somenthig like:
rootProject.ext.myproperty
rootProject.ext.myarray.name0
I know this question is old but I stumbled upon it while attempting to do a similar thing.
After trial and error and reading through the build system source I figured it out.
variants.all { variant ->
println("${variant.name.capitalize()}")
println(variant.getBuildType().myFoo)
println("------")
}
With this you'll be able to read the ExtraPropertiesExtensions from the different variants.
My output:
Debug
true
------
Release
true
------
Something
false
------
Here are the files I looked through to figure it out:
ApplicationVariantImpl and DefaultBuildType
project.hasProperty 'propName'
(parens optional when possible in groovy, prefer 'String' over "GString")

Categories

Resources