Passing -P parameters to gradle from android studio - android

Is there a functionality inside android studio to do things like this.
Basically my gradle script reads parameter named version based on which it sets dependency version of a certain library.
So when I do gradlew -Pversion=‘1.2.3' I get this string inside gradle. But this only works if I invoke gradle from console.
Is there a way to pass parameters to gradle when started using configuration for project inside Android Studio (pressing little play triangle)?
NOTE:I did find Gradle VM options and Script prameters under default configs but adding -Pversion=‘1.2.3' there doesn't seem to have an effect.

In order to provide parameter to run option of Android Studio you should setup them under AndroidStudios Compile Preferences
AndroidStudio > Preferences...
Under Compiler: ComandLineOptions

Run > Edit Configurations..
Replace "abcdef" in Script parameters by your params.

For example let's try to pass server base endpoint while building project. First we need to define a method which gets url and sets it
def serverUrl = "https://mydefaulturl.com"
task(runProgram){
if(project.hasProperty("url")){
serverUrl = url;
}
}
In your buildTypes create your base url with this value:
debug{
buildConfigField("java.lang.String","BASE_URL","$serverUrl")
}
Now we can pass debug build an url and use it.
You can build your project from terminal with the command below:
./gradlew installDebug task runProgram '-Purl="https://yournewurl.com"'

Put version="1.2.3" in gradle.properties or under
buildscript {
ext{
version="1.2.3"
}
...
}

Related

How to add gradle's task parameter in Android Studio?

We are going to debug our Android app by adding some properties in app.properties and pre-process it in the Kotlin codes.
We wrote build.gradle like:
task dailytest {
doLast {
File testProperty = new File('assets/app.properties')
testProperty.append("\ndaily_test=true")
testProperty.append("\nfps_sample_interval_ms=")
testProperty.append(fps_sample_interval_ms)
testProperty.append("\ndrop_stack_sample_interval_ms=")
testProperty.append(drop_stack_sample_interval_ms)
testProperty.append("\nmin_drop_count_to_log=")
testProperty.append(min_drop_count_to_log)
}
}
And we compile it in command line using:
./gradlew dailytest -Pfps_sample_interval_ms="100" -Pdrop_stack_sample_interval_ms="100" -Pmin_drop_count_to_log="1" :connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.myapp.sub.MainActivityTest#test_click_shelf
I was wondering if maybe we could run this test case in Android Studio by adding some confirmations?
We did try to add ::dailytest in the Before launch part, but we couldn't manage to find a way to add the custom parameters.
You can have an afterEvaluate block in your build.gradle to run your task when you build your app, something like this:
afterEvaluate {
lint.dependsOn dailytest
}

How to generate OpenAPI sources from gradle when building Android app

What I'm trying to achieve
I'm trying to generate my REST API client for Android using OpenAPI Generator from the build.gradle script. That way, I wouldn't have to run the generator command line every time the specs change. Ideally, this would be generated when I build/assemble my app, and the sources would end up in the java (generated) folder, where generated sources are then accessible from the code (this is what happens with the BuildConfig.java file for example).
What I've tried so far
Following this link from their official GitHub, here's the build.gradle file I ended up with:
apply plugin: 'com.android.application'
apply plugin: 'org.openapi.generator'
...
openApiValidate {
inputSpec = "$rootDir/app/src/main/openapi/my-api.yaml"
recommend = true
}
openApiGenerate {
generatorName = "java"
inputSpec = "$rootDir/app/src/main/openapi/my-api.yaml"
outputDir = "$buildDir/generated/openapi"
groupId = "$project.group"
id = "$project.name-openapi"
version = "$project.version"
apiPackage = "com.example.mypackage.api"
invokerPackage = "com.example.mypackage.invoker"
modelPackage = "com.example.mypackage.model"
configOptions = [
java8 : "true",
dateLibrary : "java8",
library : "retrofit2"
]
}
...
First, I've never managed to get the API generated with the build/assemble task, even when I tried adding:
compileJava.dependsOn tasks.openApiGenerate
or
assemble.dependsOn tasks.openApiGenerate
The only way I could generate the sources was by manually triggering the openApiGenerate task:
Then, when I do generate my sources this way, they end up in the build folder but aren't accessible from my code, and aren't visible in the java (generated) folder:
I then have to manually copy/paste the generated source files to my project sources in order to use the API.
Even though I'm able to work around these issues by adding manual procedures, it would be way more maintainable if the whole process was simply automatic. I was able to achieve a similar result with another tool, Protobuf. Indeed, my gradle task gets triggered every time I build the app, and the sources end up in the java (generated) folder, so I don't have to do any additional work. The task is much simpler though, so I assume the main work that I'm not able to replicate with OpenAPI Generator is handled by the Protobuf plugin itself.
You have to specify path to the generated sources as a custom source set for your Gradle module, which is app in this case, as described here – https://developer.android.com/studio/build/build-variants#configure-sourcesets. That way Gradle will treat your sources as accessible from your code.
Something like this:
android {
...
sourceSets {
main {
java.srcDirs = ['build/generated/openapi/src/main/java']
}
}
...
}
I solved the issue you described like this, I'm using gradle.kts however.
See my build.gradle.kts
plugins {
// Your other plugins
id("org.openapi.generator") version "5.3.0"
}
openApiGenerate {
generatorName.set("kotlin")
inputSpec.set("$rootDir/app/src/main/openapi/my-api.yaml")
outputDir.set("$buildDir/generated/api")
// Your other specification
}
application {
// Your other code
sourceSets {
main {
java {
// TODO: Set this path according to what was generated for you
srcDir("$buildDir/generated/api/src/main/kotlin")
}
}
}
}
tasks.compileKotlin {
dependsOn(tasks.openApiGenerate)
}
You need to build the application at least once for the IDE to detect the library (at least this is the case for me in Intellij)
Your build should automatically generate the open api classes , to refer the generated classes in your java project you should add the generated class path to your source directory like it was mentioned in the other answers
https://developer.android.com/studio/build/build-variants#configure-sourcesets
As far as the task dependency goes , in android tasks are generated after configuration thus for gradle to recognize the task , wrap it inside afterEvaluate block like
afterEvaluate {
tasks.compileDebugJavaWithJavac.dependsOn(tasks.openApiGenerate)
}
I had this issue, and this answer https://stackoverflow.com/a/55646891/14111809 led me to a more informative error:
error: incompatible types: Object cannot be converted to Annotation
#java.lang.Object()
Taking a look at the generated files that were causing this error, noticed:
import com.squareup.moshi.Json;
After including a Moshi in the app build.gradle, the build succeeded and the generated code was accessible.
implementation("com.squareup.moshi:moshi-kotlin:1.13.0")

Testing inconvenience: Android Studio JUnit vs Gradle based: testOptions ignored by Android Studio

The following was done with Android Studio 3.4, Android Gradle Plugin 3.3.2 and Gradle 4.10.3.
In the build.gradle file, I have configured some unit test options like this:
android {
testOptions {
unitTests.all {
systemProperty "debug","true"
}
}
}
I do have a test function that tries to read this property:
package com.demo;
public class SysPropTestDemo {
#Test
public static void dumpSysProps() {
System.out.println("sysprop(debug)=" + System.getProperty("debug"));
}
}
When run via command line gradlew test --test com.demo.SysPropTestDemo I will get the property debug set correctly to true. If I run the same test via Android Studio without setting any options, the value shown will be null.
In order to get the same result from Android Studio, I explicitly have to enter some values in the "Run/Debug Configurations" panel, i.e something like -Ddebug=true in the VM options.
Now this is a trivial example, but what I really want to do, is to add some path to the java.library.path property in order to be able to load a JNI library compiled within the project. (I do need to write some tests that make use a modified SQLite lib, so not using JNI is not an option here)
It does work when setting additional options, but I think this is very inconvenient, since I can't enter a variable based value in the configuration options (or at least, I don't know how to). To sum it up: when setting or changing values, I do have to go through a bunch of config screens where I would really prefer to have one place in a config file.
Shouldn't Android Studio somehow make use of the values specified in the build.gradle file? If not, the docs don't make it clear that the testOptions.unitTests.all settings can only be used via gradlew invocation.
Skybow,
I feel you have two questions
1. How to load jni lib for androidTest(not for 'test[non instrumented unit tests])
- copy your jni library in corresponding folder [JNI libraries: [app/src/androidTestFLAVORNAMEDebug/jniLibs]
- load your jni library
static {
try {
System.loadLibrary("xyzjni");
} catch (Exception e) {
Logger.error("Exception on loading the jni library : " + e.getMessage());
}
}
2. How to make android studio use your config variables defined for unitTests.
- It would have great if some text file is there which has all configs.
- Or it is part of build.gradle
- I don't have any detail on this.

Is there a way to change the gradle.properties file in Unity

Unity has a default gradle.properties file that gets added during the build process. While its possible to change the build.gradle and the settings.gradle files as mentioned
here https://docs.unity3d.com/Manual/android-gradle-overview.html
there is no mention of being able to change gradle.properties within the unity docs. The file also gets recreated every build attempt so editing it within the temp/gradleOut after a build and building again doesn't work. I know exporting the project is possible as well, but I'm looking for a solution where the project can be run directly from unity.
Btw this question is NOT a duplicate of this question How to use Gradle in Unity
The answer here has nothing to do with modifying the gradle.properties file.
This is a duplicate of this question that got incorrectly marked as a duplicate how to change default gradle.properties of Unity?
Maybe my answer is a bit outdated but in Unity 2020 you can do it in:
Player Settings -> Tab Android (with robot obviously) -> Publishing Settings -> Custom Gradle Properties Template (checkbox).
After enabling the checkbox you will see the path to gradleTemplate.properties (usually it appears in Assets/Plugins/Android directory) file which will be merged with final gradle.properties.
Everything you need you can write to the end of file after **ADDITIONAL_PROPERTIES** string.
Example:
org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
org.gradle.parallel=true
android.enableR8=**MINIFY_WITH_R_EIGHT**
**ADDITIONAL_PROPERTIES**
android.useAndroidX = true // I added this property to fix error: This project uses AndroidX dependencies, but the 'android.useAndroidX' property is not enabled. Set this property to true in the gradle.properties file and retry.
Also on screenshot:
This was something that was slightly hard to discover. I was going to do a regular post build processor like I had for my iOS build, but as I was searching for a manner to load and determine where the properties file was, I ran across the following interface in the documentation : IPostGenerateGradleAndroidProject.
According to the documentation:
Implement this interface to receive a callback after the Android
Gradle project is generated.
So below is my initial brute force implementation for turning on androidX and jetifier.
public class AndroidPostBuildProcessor : IPostGenerateGradleAndroidProject
{
public int callbackOrder
{
get
{
return 999;
}
}
void IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject(string path)
{
Debug.Log("Bulid path : " + path);
string gradlePropertiesFile = path + "/gradle.properties";
if (File.Exists(gradlePropertiesFile))
{
File.Delete(gradlePropertiesFile);
}
StreamWriter writer = File.CreateText(gradlePropertiesFile);
writer.WriteLine("org.gradle.jvmargs=-Xmx4096M");
writer.WriteLine("android.useAndroidX=true");
writer.WriteLine("android.enableJetifier=true");
writer.Flush();
writer.Close();
}
}
Theoretically you should be able to manipulate the generated gradle project in any manner to your choosing during the post build processor. Some additional tools might be helpful, like the PBXProject support on iOS, but until then, this will do.
IPostGenerateGradleAndroidProject is a new Interface added after Unity2018.
As my project based on Unity2017, it's not a good solution. Then I found this. A solution with Gradle.
([rootProject] + (rootProject.subprojects as List)).each {
ext {
it.setProperty("android.useAndroidX", true)
it.setProperty("android.enableJetifier", true)
}
}
Although this is not a perfect solution, you can use the "Export Project" option.
Build Settings
After exporting the project, you can modify gradle.properties and build using AndroidStudio or command line.
In the newer Unity versions (2019.4+) it is possible to generate a custom gradle properties template by going to Project Settings > Player > (Android Tab) > Other Settings > and marking "Custom Gradle Properties Template".
After selecting that a gradleTemplate.properties file is generated at "Assets/Plugins/Android/gradleTemplate.properties".
This is the best way of generating the file since it is git friendly and preserves other settings.

Access project related data from Gradle command

I need project related data like project name,app version and its main module from gradle based android project. I have tried various tasks like project,properties but none of it giving me specific information i need.
Is there a way to find version code,app name and main android module using gradle in command line?
Using "BuildConfig" global variable you will get
boolean DEBUG
String APPLICATION_ID
String BUILD_TYPE
String FLAVOR
int VERSION_CODE
String VERSION_NAME
eg :- BuildConfig.APPLICATION_ID
and if you defined any global data in gradle like
debug {
buildConfigField "String", "BASE_URL", '"http://172.16.1.175:8080/api/"'
debuggable true
}
you will get this details also
BuildConfig.BASE_URL
You can probably write your own custom gradle task for doing that. Add this code snippet in your app build.gradle, where you define your android plugin and run it from console. You can format output like you need it and use other data from build script.
task hello<<{
println("versionCode = ${android.defaultConfig.versionCode}")
println("applicationId = ${android.defaultConfig.applicationId}")
println("minSDK = ${android.defaultConfig.minSdkVersion}")
}
you can use resValue for that to get value
Gradle
defaultConfig {
//other config
resValue "String","versionCode","1"
}
your class
context.getString(R.string.versionCode);
I don't know if it suits, you can create one common init gradle file, which you run from command line, so it is not a source code manipulation, where you print out all necessary data. But gradle output is dirty.
This is snippet of init.gradle which is in /Users/username
allprojects{
afterEvaluate({//listen for project evaluation
println(project.name)//it is supposed to be 2 projects "ProjName" and "app"
if(project.name.equalsIgnoreCase("app")){//or any other condtion to check if it is inner android project
project.task("getVersion",{
println("versionCode = ${android.defaultConfig.versionCode}")
})
}
});
}
you start this script like ./gradlew --I /Users/username/init.gradle
This is what I have as an output
music
app
versionCode = 1
:help
Welcome to Gradle 2.4.
To run a build, run gradlew <task> ...
To see a list of available tasks, run gradlew tasks
To see a list of command-line options, run gradlew --help
To see more detail about a task, run gradlew help --task <task>
BUILD SUCCESSFUL
Total time: 6.929 secs
This build could be faster, please consider using the Gradle Daemon: http://gradle.org/docs/2.4/userguide/gradle_daemon.html
So this is what could be done, another available option is to parse build.gradle file or manifest.xml in bash, or write own console utility that will do it with a cleaner output.
I hope I helped.

Categories

Resources