How can custom compilation parameters be synchronized through the Android studio project? - android-studio

Some parameters in my project need to be passed in at compile time.
So there is such a fragment in my build.gradle file:
assemble {
description 'Check the necessary parameters and terminate compilation if they do not exist.'
if (!project.hasProperty('customArgs')) {
throw new RuntimeException("Parameter customArgs is not defined")
}
}
When I compile, I will use the command gradle build -PcustomArgs=1234
Everything was fine until I imported the project into Android studio.
Gradle project sync is always fails.
That is to say, in the process of project synchronization, I can't find any place where I can set parameters.
In other words, how to set the parameters of sync in Android Studio?

You should move this custom behavior from the configuration phase to the execution phase. Otherwise Android Studio will execute it when configuring you project.
assemble {
doLast {
description 'Check the necessary parameters and terminate compilation if they do not exist.'
if (!project.hasProperty('customArgs')) {
throw new RuntimeException("Parameter customArgs is not defined")
}
}
}
More informations here

Related

Android studio doest not show error in kotlin class after update gradle plugin

I work in the Android 4.1.2 studio. I updated Gradle plugin
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.android.tools.build:gradle:4.1.2'
and
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
After that, I tried to build the apk, but the build failed due to errors in kotlin class, for example: "'handleMessage' overrides nothing " for Handler class, and "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type" for intent.getParcelableExtra. The Android studio itself does not show me such errors in kotlin class. Can you tell me what this is related to and how I can enable the display of errors in android studio
I have tried rebuild, clean , invalidate & restart.
Click the "Handler" to open the Decompiled Handler.class, search "handleMessage" in it, the new definition looks as below:
public void handleMessage(#NonNull Message msg) {
throw new RuntimeException("Stub!");
}
So the argument msg has been changed to #NonNull.
Therefore, to fix this issue, the original override statement
override fun handleMessage(message: Message?)
should be updated to remove the ? to match the function definition.
override fun handleMessage(message: Message)

Android Studio - Building library aar file doesn't append flavor or buildType to output

I am running assemble for my library module , I see from logs that it should generate two files myLib-release.aar and myLib-debug.aar inside the myLib/build/outputs/ folder.
However, I always only find one lib there that is myLib.aar, it doesn't matter if I run assemble for both, assembleDbug or assembleRelease.
Why is this happening?
According to this discussion it is an error (or planned feature) in gradle, up to date it is still the same.
https://github.com/gradle/gradle/issues/8328
Workaround can be to implement this:
// in library/library.gradle
afterEvaluate {
def debugFile = file("$buildDir/outputs/aar/library.aar")
tasks.named("assembleDebug").configure {
doLast {
debugFile.renameTo("$buildDir/outputs/aar/library-debug.aar")
}
}
tasks.named("assembleRelease").configure {
doLast {
debugFile.renameTo("$buildDir/outputs/aar/library-release.aar")
}
}
}
You may then implement copy tasks as desired.

Create external link in Javadoc using Gradle in Android Studio

I have created a Gradle task that generates a javadoc using Doclava:
My code (the arguments of some of my methods) references classes defined in Android. When Javadoc is built, these references link correctly to the Android online reference. However, when I use the #ling tag to link to Android references, it does not work and I get something like:
configurations {
jaxDoclet
classpaths
}
dependencies {
// For Doclava JavaDoc
jaxDoclet("com.google.doclava:doclava:1.0.6")
classpaths files('build/intermediates/classes/debug')
classpaths project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.allJava
source += fileTree("build/generated/source/r/debug")
title = null
options {
docletpath = configurations.jaxDoclet.files.asType(List)
doclet "com.google.doclava.Doclava"
bootClasspath new File(System.getenv('JAVA_HOME') + "/jre/lib/rt.jar")
classpath += configurations.classpaths.files.asType(List)
addStringOption "public"
addStringOption "federate android", "http://d.android.com/reference"
addStringOption "federationxml android", "http://doclava.googlecode.com/svn/static/api/android-10.xml"
}
}
warning 101: Unresolved link/see tag "Runnable" in com....
In similar questions in SO, it was advised to use -link and -linkoffline flags. However, when I do that I get:
javadoc: error - invalid flag: -linkoffline
I am using Android Studio 1.5.1 and Gradle 2.11.
Update
It seems that Doclava may not support -link and -linksoffline according to these tickets. If I use the default doclet, links work correctly.

Set the project properties in subclassed gradle task

I am defining a gradle task "launchIPad2Simulator" that is subclassing another already defined task "launchIPadSimulatorfrom" in robovm gradle plugin. The goal is to set the project properties which are defining which simulator will run.
// Run the IPad2 simulator
task launchIPad2Simulator2(type: org.robovm.gradle.tasks.IPadSimulatorTask) {
project.setProperty("robovm.device.name", "iPad-2")
project.setProperty("robovm.arch", "x86")
}
But the problem is, I must first define the properties in the gradle.properties file. They don't even need to have any value assigned. The whole content of the gradle.properties file:
robovm.device.name
robovm.arch
I would rather have gradle.properties file empty, but if the above task is then run, the error: Error:(112, 0) No such property: robovm.device.name for class: org.gradle.api.internal.project.DefaultProject_Decorated is shown.
Also if properties are only defined in task as following (gradle.properties is empty), they are ignored.
// Run the IPad2 simulator
task launchIPad2Simulator2(type: org.robovm.gradle.tasks.IPadSimulatorTask) {
project.properties.put("robovm.device.name", "iPad-2")
project.properties.put("robovm.arch", "x86")
}
So what is the correct way to dynamically set the project properties in subclassed task?
=== Edit ===
Ok now I see that setting the project properties is also not good, because in multiple tasks it gets overwritten. So maybe this shouldn't be project properties in first place.
The temp solution now is using command line invocation of tasks:
// simulator with properties launched from command line
task launchIPad2Simulator1(type: Exec) {
commandLine 'gradle', '-Probovm.device.name=iPad-2', '-Probovm.arch=x86', 'launchIPadSimulator'
}
try
task launchIPad2Simulator2(type: org.robovm.gradle.tasks.IPadSimulatorTask) {
project.ext."robovm.device.name" = "iPad-2"
project.ext."robovm.arch" = "x86"
}
this is the gradle syntax to add dynamic properites to the project object.

Android Studio -- clear application data for Instrumentation Test

How can I get Android Studio (AndroidJunitRunner) to clear application data preceding an instrumentation test without manually running adb command?
I discovered that android.support.test.runner.AndroidJUnitRunner kind of cheats -- it never actually invokes connectedCheck or connectedAndroidTest.
When run from command line $ gradle connectedCheck
:MyMainApp:assembleDebug UP-TO-DATE
:MyMainApp:assembleDebugTest UP-TO-DATE
:MyMainApp:clearMainAppData
:MyMainApp:connectedCheck
When run from within IDE by clicking the instrumentation test configuration (green Android robot logo with red/green arrows)
**Executing tasks: [:MyMainAppApp:assembleDebug, :MyMainAppApp:assembleDebugTest]**
As you can see, the last gradle target is assembleDebugTest
I had added a hook onto connectedCheck in build.gradle to clear the data of the main app before starting the instrumentation test.
// Run 'adb' shell command to clear application data of main app for 'debug' variant
task clearMainAppData(type: Exec) {
// we have to iterate to find the 'debug' variant to obtain a variant reference
android.applicationVariants.all { variant ->
if (variant.name.equals("debug")) {
def clearDataCommand = ['adb', 'shell', 'pm', 'clear', getPackageName(variant)]
println "Clearing application data of ${variant.name} variant: [${clearDataCommand}]"
commandLine clearDataCommand
}
}
}
// Clear Application Data (once) before running instrumentation test
tasks.whenTaskAdded { task ->
// Both of these targets are equivalent today, although in future connectedCheck
// will also include connectedUiAutomatorTest (not implemented yet)
if(task.name.equals("connectedAndroidTest") || task.name.equals("connectedCheck" )){
task.dependsOn(clearMainAppData)
}
}
I realize that alternatively I could implement a 'clear data' button in the main app and have the instrumentation app click through the UI, but I find that solution undesirable.
I looked at AndroidJUnitRunner API and there are hooks via Runlistener interface but hooks are during the context of the test app, i.e. running on device, and Android forbids one app from modifying another app.
http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html
Best answer goes to you if you can help me trigger one of the following automatically from within Android Studio:
execute a command line adb shell pm clear my.main.app.package,
or preferably invoke my gradle task clearMainAppData
I'm also all ears if there is an alternate way. Surely with device testing automation there should be a clear way to clear application data?
Thank you!
I know it's been a while, and hopefully by now you will have this issue sorted.
I ran into that same issue today, and crashed here without any solution.
But I managed to make it work by calling my task from the test configuration.
Step 1 : Go to your test configuration
Step 2 : Simply add the gradle task you created
By the way, the task in my case simply looks like this :
task clearData(type: Exec) {
def clearDataCommand = ['adb', 'shell', 'pm', 'clear', 'com.your.application']
commandLine clearDataCommand
}
Hope this will help someone :)
With Android Test Orchestrator it is easier to provide this option via gradle script.
android {
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
}
Below is the link for Android Test Orchestrator
https://developer.android.com/training/testing/junit-runner#using-android-test-orchestrator

Resources