About the "new" AGP API to get the app apk, I need...
# android
c
About the "new" AGP API to get the app apk, I need to use the apk as an input for a task, I do:
Copy code
val testApkDir: Provider<Directory> = variant.androidTest!!.artifacts.get(SingleArtifact.APK)
val builtArtifactsLoader: BuiltArtifactsLoader = ... // That's from Android Gradle Plugin

myTask.configure {
  // testApk is RegularFileProperty, and I want to keep the dependency to the task generating it
  testApk.value(
    testApkDir.map {
      it.file(builtArtifactsLoader.load(it)!!.elements.single().outputFile)
    }
  )
}
and everything is fine until I try to enable the configuration-cache, it tries to get the file too early and
load
returns no elements As a workaround I'm using
testApkDir
as input directly, but I wonder if that's safe, I mean, may anything in this directory change? timestamp? absolute path? if it wasn't android specific I would expect to use directly the output of the
package
task (being a
Provider<File>
)
hum... I just did something simple, debug it, and he json is quite simple actually:
Copy code
{
  "version": 3,
  "artifactType": {
    "type": "APK",
    "kind": "Directory"
  },
  "applicationId": "testApp",
  "variantName": "debug",
  "elements": [
    {
      "type": "SINGLE",
      "filters": [],
      "attributes": [],
      "versionCode": 1,
      "versionName": "1.0",
      "outputFile": "app-debug.apk"
    }
  ],
  "elementType": "File"
}
so I guess it's just fine, the Directory only contains that json and the apk
t
I ran into the same exact problem. I can share my code with you later, that is safe from both a CC and AGP perspective
sharing my solution but absolutely interested in yours @tony
t
I tried to encapsulate it all into a single gist. Let me know if you have any questions. I like this approach, despite its verbosity in setup, because it uses the AGP APIs, meaning it should be safe unless AGP deliberately breaks their API. It also saves downstream users (task authors) from having to deal with
BuiltArtifactsLoader
directly. I've also verified it works with configuration cache via automated testing, and it still correctly sets up implicit task dependencies https://gist.github.com/autonomousapps/09b4737e5bb860d9388976354bf54673
c
I was trying to understand why your map (un the load) works, but actually it doesn't, you are using as input the AndroidApks class (nested) and it has the Property<Directory> as input, so, you are really using the Directory, not the RegularFile as input. If the json file changed, even if the APK was identical, the task would be invalidated.
Don't get me wrong, it's encapsulating it better, but the tasks inputs, from the BuildCache perspective, are exactly the same
t
I'm not sure why it would be a point against it that it's using the directory as an input. that is what AGP gives us, unfortunately. it's also unclear why the json would change if the apk didn't. if it does, rerun the task, fine by me 🤷
my goal was exactly to encapsulate all the wiring so task authors don't have to care, and in a way that would be maintainable. I think I achieved that, more or less
👍 1
c
I was worried about using the Directory because I didn't know what can be in there. When I took a look to the json I felt better, I was afraid of having a timestamp (like "created_at") or something like that that could change on every build, but luckily there is none. Also in my case, the task can have as input that Provider<Directory> or the output of another task (long story, to run library tests I don't need the app apk, FTL doesn't allow you to use the same test APK, so I'm using a small app for that)
x
What you're doing at config time (reading the content of the json file) must be done at runtime in your task. See this gradle recipe with the configuration and task code.
c
Yes Xavier, and it's how I did it finally. I wanted a file because I didn't know what's the content of the directory, but I did look at it and saw the json doesn't contain any changing data (no timestamps for example).