1# Getting started 2 3[TOC] 4 5This page describes how to set up your workstation to check out source code, 6make simple changes in Android Studio, and upload commits to Gerrit for review. 7 8This page does **not** cover best practices for the content of changes. Please 9see [Life of a Jetpack Feature](/docs/loaf.md) for details on 10creating and releasing a library or 11[API Guidelines](/docs/api_guidelines/index.md) for best 12practices regarding library development. 13 14## Workstation setup {#setup} 15 16This section will help you install the `repo` tool, which is used for Git branch 17and commit management. If you want to learn more about `repo`, see the 18[Repo Command Reference](https://source.android.com/setup/develop/repo). 19 20NOTE The `repo` tool uses Git submodules under the hood, and it is possible to 21skip using the tool in favor of using submodules directly. If you prefer to use 22submodules, look for notes anywhere that `repo` is mentioned in this document. 23Submodule users can skip Workstation setup. 24 25### Linux and MacOS {#setup-linux-mac} 26 27First, download `repo` using `curl`. 28 29```shell 30test -d ~/bin || mkdir ~/bin 31curl https://storage.googleapis.com/git-repo-downloads/repo \ 32 > ~/bin/repo && chmod 700 ~/bin/repo 33``` 34 35Then, modify `~/.zshrc` (or `~/.bash_profile` if using `bash`) to ensure you can 36find local binaries from the command line. We assume you're using `zsh`, but the 37following should work with `bash` as well. 38 39```shell 40export PATH=~/bin:$PATH 41``` 42 43> NOTE: When using quotes (`"~/bin"`), `~` does not expand and the path is 44> invalid. (Possibly `bash` only?) 45 46Next, add the following lines to `~/.zshrc` (or `~/.bash_profile` if using 47`bash`) aliasing the `repo` command to run with `python3`: 48 49```shell 50# Force repo to run with Python3 51function repo() { 52 command python3 ~/bin/repo $@ 53} 54``` 55 56Finally, you will need to either start a new terminal session or run `source 57~/.zshrc` (or `source ~/.bash_profile` if using `bash`) to enable the changes. 58 59> NOTE: If you encounter the following warning about Python 2 being no longer 60> supported, you will need to install Python 3 from the 61> [official website](https://www.python.org). 62> 63> ```shell {.bad} 64> repo: warning: Python 2 is no longer supported; Please upgrade to Python 3.6+. 65> ``` 66 67> NOTE: If you encounter an SSL `CERTIFICATE_VERIFY_FAILED` error: 68> 69> ```shell {.bad} 70> Downloading Repo source from https://gerrit.googlesource.com/git-repo 71> fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle 72> fatal: error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (\_ssl.c:997) 73> ``` 74> 75> Run the `Install Certificates.command` in the Python folder of Application 76> (e.g. `/Applications/Python\ 3.11/Install\ Certificates.command`). For more 77> information about SSL/TLS certificate validation, you can read the "Important 78> Information" displayed during Python installation. 79 80### Windows {#setup-win} 81 82Sorry, Windows is not a supported platform for AndroidX development. 83 84## Set up access control {#access} 85 86### Authenticate to AOSP Gerrit {#access-gerrit} 87 88Before you can upload changes, you will need to associate your Google 89credentials with the AOSP Gerrit code review system by signing in to 90[android-review.googlesource.com](https://android-review.googlesource.com) at 91least once using the account you will use to submit patches. 92 93Next, you will need to 94[set up authentication](https://android.googlesource.com/new-password). 95This will give you a shell command to update your local Git cookies, which will 96allow you to upload changes. 97 98Finally, you will need to accept the 99[CLA for new contributors](https://android-review.googlesource.com/settings/new-agreement). 100 101## Check out the source {#source} 102 103Like ChromeOS, Chromium, and the Android OS, we develop in the open as much as 104possible. All feature development occurs in the public 105[`androidx-main`](https://android.googlesource.com/platform/superproject/+/refs/heads/androidx-main) 106`repo` branch of the Android Open Source Project, with majority of the code in 107the 108[`frameworks/support` git repository](https://android.googlesource.com/platform/frameworks/support/+/androidx-main). 109 110As of 2024/10/10, you will need about XXX GB for a clean checkout or YYY GB for 111a fully-built checkout. 112 113### Synchronize the branch {#source-checkout} 114 115Use the following commands to check out your branch. 116 117#### Public main development branch {#androidx-main} 118 119All development should occur in this branch unless otherwise specified by the 120AndroidX Core team. 121 122The following command will check out the public main development branch: 123 124```shell 125mkdir androidx-main && cd androidx-main 126repo init -u https://android.googlesource.com/platform/manifest \ 127 -b androidx-main --partial-clone --clone-filter=blob:limit=10M 128repo sync -c -j32 129``` 130 131NOTE On MacOS, if you receive an SSL error like `SSL: CERTIFICATE_VERIFY_FAILED` 132you may need to install Python3 and boot strap the SSL certificates in the 133included version of pip. You can execute `Install Certificates.command` under 134`/Applications/Python 3.6/` to do so. 135 136NOTE On MacOS, if you receive a Repo or GPG error like `repo: error: "gpg" 137failed with exit status -6` with cause `md_enable: algorithm 10 not available` 138you may need to install a build of `gpg` that supports SHA512, such as the 139latest version available from [Homebrew](https://brew.sh/) using `brew install 140gpg`. 141 142### Increase Git rename limit {#source-config} 143 144To ensure `git` can detect diffs and renames across significant changes (namely, 145the `androidx.*` package rename), we recommend that you set the following `git 146config` properties: 147 148```shell 149git config --global merge.renameLimit 999999 150git config --global diff.renameLimit 999999 151``` 152 153### Set up Git file exclusions {#source-exclude} 154 155Mac users should consider adding `.DS_Store` to a global `.gitignore` file to 156avoid accidentally checking in local metadata files: 157 158```shell 159echo .DS_Store>>~/.gitignore 160git config --global core.excludesFile '~/.gitignore' 161``` 162 163### To check out older sources, use the superproject {#source-historical} 164 165The 166[git superproject](https://android.googlesource.com/platform/superproject/+/androidx-main) 167contains a history of the matching exact commits of each git repository over 168time, and it can be 169[checked out directly via git](https://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules) 170 171### Troubleshooting 172 173> NOTE: If the repo manifest changes -- for example when we update the version 174> of `platform-tools` by pointing it to a different git project -- you may see 175> the following error during`repo sync`: 176> 177> ```shell 178> error.GitError: Cannot fetch --force-sync not enabled; cannot overwrite a local work tree. 179> ... 180> error: Unable to fully sync the tree. 181> error: Downloading network changes failed. 182> ``` 183> 184> This indicates that Studio or some other process has made changes in the git 185> project that has been replaced or removed. You can force `repo sync` to 186> discard these changes and check out the correct git project by adding the 187> `--force-sync` argument: 188> 189> ```shell 190> repo sync -j32 --force-sync 191> ``` 192 193## Explore source code from a browser {#code-search} 194 195`androidx-main` has a publicly-accessible 196[code search](https://cs.android.com/androidx/platform/frameworks/support) that 197allows you to explore all of the source code in the repository. Links to this 198URL may be shared on the public issue tracked and other external sites. 199 200### Custom search engine for `androidx-main` {#custom-search-engine} 201 202We recommend setting up a custom search engine in Chrome as a faster (and 203publicly-accessible) alternative to `cs/`. 204 2051. Open `chrome://settings/searchEngines` 2061. Click the `Add` button 2071. Enter a name for your search engine, ex. "AndroidX Code Search" 2081. Enter a keyword, ex. "csa" 2091. Enter the following URL: 210 `https://cs.android.com/search?q=%s&ss=androidx%2Fplatform%2Fframeworks%2Fsupport` 2111. Click the `Add` button 212 213Now you can select the Chrome omnibox, type in `csa` and press tab, then enter a 214query to search for, e.g. `AppCompatButton file:appcompat`, and press the 215`Enter` key to get to the search result page. 216 217## Develop in Android Studio {#studio} 218 219Library development uses a curated version of Android Studio to ensure 220compatibility between various components of the development workflow. 221 222From the `frameworks/support` directory, you can use `./studiow m` (short for 223`ANDROIDX_PROJECTS=main ./gradlew studio`) to automatically download and run the 224correct version of Studio to work on the `main` set of androidx projects 225(non-Compose Jetpack libraries). 226[studiow](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:studiow) 227also supports several other arguments like `all` for other subsets of the 228projects (run `./studiow` for help). 229 230Next, open the `framework/support` project root from your checkout. If Studio 231asks you which SDK you would like to use, select `Use project SDK`. Importing 232projects may take a while, but once that finishes you can use Studio as you 233normally would for application or library development -- right-click on a test 234or sample to run or debug it, search through classes, and so on. 235 236> NOTE: You should choose "Use project SDK" when prompted by Studio. If you 237> picked "Android Studio SDK" by mistake, don't panic! You can fix this by 238> opening `File > Project Structure > Platform Settings > SDKs` and manually 239> setting the Android SDK home path to 240> `<project-root>/prebuilts/fullsdk-<platform>`. 241 242### Troubleshooting {#studio-troubleshooting} 243 244* If you've updated to macOS Ventura and receive a "xcrun: error: invalid 245 active developer path" message when running Studio, reinstall Xcode using 246 `xcode-select --install`. If that does not work, you will need to download 247 Xcode. 248* If you get a “Unregistered VCS root detected” message, click “Add root” to 249 enable the Git/VCS integration for Android Studio. 250* If you see any errors (red underlines), click Gradle's elephant button in 251 the toolbar (or `File > Sync Project with Gradle Files`) and they should 252 resolve once the build completes. 253* If you run `./studiow` with a new project set but you're still seeing the 254 old project set in `Project`, use `File > Sync Project with Gradle Files` to 255 force a re-sync. 256* If you still see errors after gradle sync, run `repo status` to check for 257 any files listed in a "deleted" status. If there are deleted files, navigate 258 to each directory containing these files and run `git reset --hard` on each 259 of the directories of the deleted files. 260* If Android Studio's UI looks scaled up, ex. twice the size it should be, you 261 may need to add the following line to your `studio64.vmoptions` file using 262 `Help > Edit Custom VM Options`: `-Dsun.java2d.uiScale.enabled=false` 263* If you don't see a specific Gradle task listed in Studio's Gradle pane, 264 check the following: 265 * Studio might be running a different project subset than the one 266 intended. For example, `./studiow main` only loads the `main` set of 267 androidx projects; run `./studiow compose` to load the tasks specific to 268 Compose. 269 * Gradle tasks aren't being loaded. Under Studio's settings => 270 Experimental, make sure that "Do not build Gradle task list during 271 Gradle sync" is unchecked. Note that unchecking this can reduce Studio's 272 performance. 273 274If in the future you encounter unexpected errors in Studio and you want to check 275for the possibility it is due to some incorrect settings or other generated 276files, you can run `./studiow --clean main <project subset>` or `./studiow 277--reinstall <project subset>` to clean generated files or reinstall Studio. 278 279### Enabling Compose `@Preview` annotation previews 280 281Add the following dependencies to your project's `build.gradle`: 282 283```groovy 284dependencies { 285 implementation(project(":compose:ui:ui-tooling-preview")) 286 debugImplementation(project(":compose:ui:ui-tooling")) 287} 288``` 289 290Then, 291[use it like you would on an external project](https://developer.android.com/jetpack/compose/tooling). 292 293## Making changes {#changes} 294 295Similar to Android framework development, library development should occur in 296CL-specific working branches. Use `repo` to create, upload, and abandon local 297branches. Use `git` to manage changes within a local branch. 298 299```shell 300cd path/to/checkout/frameworks/support/ 301repo start my_branch_name . 302# make necessary code changes 303# use git to commit changes 304repo upload --cbr -t . 305``` 306 307The `--cbr` switch automatically picks the current repo branch for upload. The 308`-t` switch sets the Gerrit topic to the branch name, e.g. `my-branch-name`. You 309can refer to the 310[Android documentation](https://source.android.com/setup/create/coding-tasks#workflow) 311for a high level overview of this basic workflow. 312 313If you see the following prompt, choose `always`: 314 315``` 316Run hook scripts from https://android.googlesource.com/platform/manifest (yes/always/NO)? 317``` 318 319If the upload succeeds, you'll see an output like: 320 321``` 322remote: 323remote: New Changes: 324remote: https://android-review.googlesource.com/c/platform/frameworks/support/+/720062 Further README updates 325remote: 326``` 327 328To edit your change, use `git commit --amend`, and re-upload. 329 330NOTE If you encounter issues with `repo upload`, consider running upload with 331trace enabled, e.g. `GIT_DAPPER_TRACE=1 repo --trace upload . --cbr -y`. These 332logs can be helpful for reporting issues to the team that manages our git 333servers. 334 335NOTE If `repo upload` or any `git` command hangs and causes your CPU usage to 336skyrocket (e.g. your laptop fan sounds like a jet engine), then you may be 337hitting a rare issue with Git-on-Borg and HTTP/2. You can force `git` and `repo` 338to use HTTP/1.1 with `git config --global http.version HTTP/1.1`. 339 340### Fixing Kotlin code style errors 341 342`repo upload` automatically runs `ktfmt`, which will cause the upload to fail if 343your code has style errors, which it reports on the command line like so: 344 345``` 346[FAILED] ktfmt_hook 347 [path]/MessageListAdapter.kt:36:69: Missing newline before ")" 348``` 349 350To find and fix these errors, you can run ktfmt locally, either in a console 351window or in the Terminal tool in Android Studio. Running in the Terminal tool 352is preferable because it will surface links to your source files/lines so you 353can easily navigate to the code to fix any problems. 354 355First, to run the tool and see all of the errors, run: 356 357`./gradlew module:submodule:ktCheck` 358 359where module/submodule are the names used to refer to the module you want to 360check, such as `navigation:navigation-common`. You can also run ktfmt on the 361entire project, but that takes longer as it is checking all active modules in 362your project. 363 364Many of the errors that ktfmt finds can be automatically fixed by running 365ktFormat: 366 367`./gradlew module:submodule:ktFormat` 368 369ktFormat will report any remaining errors, but you can also run `ktCheck` again 370at any time to see an updated list of the remaining errors. 371 372## Building {#building} 373 374### Modules and Maven artifacts {#modules-and-maven-artifacts} 375 376To build a specific module, use the module's `assemble` Gradle task. For 377example, if you are working on `core` module use: 378 379```shell 380./gradlew core:core:assemble 381``` 382 383To make warnings fail your build (same as presubmit), use the `--strict` flag, 384which our gradlew expands into a few correctness-related flags including 385`-Pandroidx.validateNoUnrecognizedMessages`: 386 387```shell 388./gradlew core:core:assemble --strict 389``` 390 391To generate a local Maven artifact for the specific module and place it in 392`out/repository`, use the `publish` Gradle task: 393 394```shell 395./gradlew core:core:publish 396``` 397 398To build every module and generate the local Maven repository artifacts and 399place them in `out/repository`, use the `createArchive` Gradle task: 400 401```shell 402./gradlew createArchive 403``` 404 405To run the complete build task that our build servers use, use the corresponding 406shell script: 407 408```shell 409./busytown/androidx.sh 410``` 411 412### Attaching a debugger to the build 413 414Gradle tasks, including building a module, may be run or debugged from within 415Android Studio. To start, you need to add the task as a run configuration: you 416can do this manually by adding the corresponding task by clicking on the run 417configuration dropdown, pressing 418[`Edit Configurations`](https://www.jetbrains.com/help/idea/run-debug-gradle.html), 419and adding the corresponding task. 420 421You can also run the task through the IDE from the terminal, by using the 422[`Run highlighted command using IDE`](https://blog.jetbrains.com/idea/2020/07/run-ide-features-from-the-terminal/) 423feature - type in the task you want to run in the in-IDE terminal, and 424`ctrl+enter` / `cmd+enter` to launch this through the IDE. This will 425automatically add the configuration to the run configuration menu - you can then 426cancel the task. 427 428Once the task has been added to the run configuration menu, you can start 429debugging as with any other task by pressing the `debug` button. 430 431Note that debugging will not be available until Gradle sync has completed. 432 433#### From the command line 434 435Tasks may also be debugged from the command line, which may be useful if 436`./studiow` cannot run due to a Gradle task configuration issue. 437 4381. From the Run dropdown in Studio, select "Edit Configurations". 4391. Click the plus in the top left to create a new "Remote" configuration. Give 440 it a name and hit "Ok". 4411. Set breakpoints. 4421. Run your task with added flags: `./gradlew <your_task_here> 443 -Dorg.gradle.debug=true --no-daemon` 4441. Hit the "Debug" button to the right of the configuration dropdown to attach 445 to the process. 446 447#### Troubleshooting the debugger 448 449If you get a "Connection refused" error, it's likely because a gradle daemon is 450still running on the port specified in the config, and you can fix this by 451killing the running gradle daemons: 452 453```shell 454./gradlew --stop 455``` 456 457NOTE This is described in more detail in this 458[Medium article](https://medium.com/grandcentrix/how-to-debug-gradle-plugins-with-intellij-eef2ef681a7b). 459 460#### Attaching to an annotation processor 461 462Annotation processors run as part of the build, to debug them is similar to 463debugging the build. 464 465For a Java project: 466 467```shell 468./gradlew <your_project>:compileDebugJava --no-daemon --rerun-tasks -Dorg.gradle.debug=true 469``` 470 471For a Kotlin project: 472 473```shell 474./gradlew <your_project>:compileDebugKotlin --no-daemon --rerun-tasks -Dorg.gradle.debug=true -Dkotlin.compiler.execution.strategy="in-process" -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=n" 475``` 476 477### Optional: Enabling internal menu in IntelliJ/Studio 478 479To enable tools such as `PSI tree` inside of IntelliJ/Studio to help debug 480Android Lint checks and Metalava, you can enable the 481[internal menu](https://www.jetbrains.org/intellij/sdk/docs/reference_guide/internal_actions/enabling_internal.html) 482which is typically used for plugin and IDE development. 483 484### Reference documentation {#docs} 485 486Our reference docs (Javadocs and KotlinDocs) are published to 487https://developer.android.com/reference/androidx/packages and may be built 488locally. 489 490NOTE `./gradlew tasks` always has the canonical task information! When in doubt, 491run `./gradlew tasks` 492 493#### Generate docs 494 495To build API reference docs for both Java and Kotlin source code using Dackka, 496run the Gradle task: 497 498``` 499./gradlew docs 500``` 501 502Location of generated refdocs: 503 504* docs-public (what is published to DAC): 505 `{androidx-main}/out/androidx/docs-public/build/docs` 506* docs-tip-of-tree: `{androidx-main}/out/androidx/docs-tip-of-tree/build/docs` 507 508The generated docs are plain HTML pages with links that do not work locally. 509These issues are fixed when the docs are published to DAC, but to preview a 510local version of the docs with functioning links and CSS, run: 511 512``` 513python3 development/offlinifyDocs/offlinify_dackka_docs.py 514``` 515 516You will need to have the `bs4` Python package installed. The CSS used is not 517the same as what will be used when the docs are published. 518 519By default, this command converts the tip-of-tree docs for all libraries. To see 520more options, run: 521 522``` 523python3 development/offlinifyDocs/offlinify_dackka_docs.py --help 524``` 525 526#### Release docs 527 528To build API reference docs for published artifacts formatted for use on 529[d.android.com](http://d.android.com), run the Gradle command: 530 531``` 532./gradlew zipDocs 533``` 534 535This will create the artifact `{androidx-main}/out/dist/docs-public-0.zip`. This 536command builds docs based on the version specified in 537`{androidx-main-checkout}/frameworks/support/docs-public/build.gradle` and uses 538the prebuilt checked into 539`{androidx-main-checkout}/prebuilts/androidx/internal/androidx/`. We 540colloquially refer to this two step process of (1) updating `docs-public` and 541(2) checking in a prebuilt artifact into the prebuilts directory as 542[The Prebuilts Dance](/docs/releasing_prebuilts_dance.md#the-prebuilts-dance™). 543So, to build javadocs that will be published to 544https://developer.android.com/reference/androidx/packages, both of these steps 545need to be completed. 546 547### Updating public APIs {#updating-public-apis} 548 549Public API tasks -- including tracking, linting, and verifying compatibility -- 550are run under the following conditions based on the `androidx` configuration 551block, evaluated in order: 552 553* `runApiTasks=Yes` => yes 554* `runApiTasks=No` => no 555* `toolingProject=true` => no 556* `mavenVersion` or group version not set => no 557* Has an existing `api/` directory => yes 558* `publish=SNAPSHOT_AND_RELEASE` => yes 559* Otherwise, no 560 561If you make changes to tracked public APIs, you will need to acknowledge the 562changes by updating the `<component>/api/current.txt` and associated API files. 563This is handled automatically by the `updateApi` Gradle task: 564 565```shell 566# Run updateApi for all modules. 567./gradlew updateApi 568 569# Run updateApi for a single module, ex. appcompat-resources in group appcompat. 570./gradlew :appcompat:appcompat-resources:updateApi 571``` 572 573If you change the public APIs without updating the API file, your module will 574still build **but** your CL will fail Treehugger presubmit checks. 575 576NOTE The `updateApi` task does not generate versioned API files (e.g. 577`1.0.0-beta01.txt`) during a library's `alpha`, `rc` or stable cycles. The task 578will always generate `current.txt` API files. 579 580#### What are all these files in `api/`? {#updating-public-apis-glossary} 581 582Historical API surfaces are tracked for compatibility and docs generation 583purposes. For each version -- including `current` to represent the tip-of-tree 584version -- we record three different types of API surfaces. 585 586* `<version>.txt`: Public API surface, tracked for compatibility 587* `restricted_<version>.txt`: `@RestrictTo` API surface, tracked for 588 compatibility where necessary (see 589 [Restricted APIs](/docs/api_guidelines/index.md#restricted-api)) 590* `public_plus_experimental_<version>.txt`: Public API surface plus 591 `@RequiresOptIn` experimental API surfaces used for documentation (see 592 [Experimental APIs](/docs/api_guidelines/index.md#experimental-api)) 593 and API review 594 595NOTE: Experimental API tracking for KLib is enabled by default for KMP projects 596via parallel `updateAbi` and `checkAbi` tasks. If you have a problem with these 597tools, 598[please file an issue](https://issuetracker.google.com/issues/new?component=1102332&template=1780493). 599As a workaround, you may opt-out by setting 600`enableBinaryCompatibilityValidator = false` under 601`AndroidxMultiplatformExtension` in your library's `build.gradle` file. 602 603### Release notes & the `Relnote:` tag {#relnote} 604 605Prior to releasing, release notes are pre-populated using a script and placed 606into a Google Doc. The Google Doc is manually double checked by library owners 607before the release goes live. To auto-populate your release notes, you can use 608the semi-optional commit tag `Relnote:` in your commit, which will automatically 609include that message the commit in the pre-populated release notes. 610 611The presence of a `Relnote:` tag is required for API changes in `androidx-main`. 612 613#### How to use it? 614 615One-line release note: 616 617``` {.good} 618Relnote: Fixed a critical bug 619``` 620 621``` {.good} 622Relnote: "Fixed a critical bug" 623``` 624 625``` {.good} 626Relnote: Added the following string function: `myFoo(\"bar\")` 627``` 628 629Multi-line release note: 630 631Note: If the following lines do not contain an indent, you may hit b/165570183. 632 633``` {.good} 634Relnote: "We're launching this awesome new feature! It solves a whole list of 635 problems that require a lot of explaining! " 636``` 637 638``` {.good} 639Relnote: """Added the following string function: `myFoo("bar")` 640 It will fix cases where you have to call `myFoo("baz").myBar("bar")` 641 """ 642``` 643 644Opt out of the Relnote tag: 645 646``` {.good} 647Relnote: N/A 648``` 649 650``` {.good} 651Relnote: NA 652``` 653 654NOT VALID: 655 656``` {.bad} 657Relnote: This is an INVALID multi-line release note. Our current scripts won't 658include anything beyond the first line. The script has no way of knowing when 659the release note actually stops. 660``` 661 662``` {.bad} 663Relnote: This is an INVALID multi-line release note. "Quotes" need to be 664 escaped in order for them to be parsed properly. 665``` 666 667### Common build errors 668 669#### Diagnosing build failures 670 671If you've encountered a build failure and you're not sure what is triggering it, 672then please run 673`./development/diagnose-build-failure/diagnose-build-failure.sh`. 674 675This script can categorize your build failure into one of the following 676categories: 677 678* The Gradle Daemon is saving state in memory and triggering a failure 679* Your source files have been changed and/or incompatible git commits have 680 been checked out 681* Some file in the out/ dir is triggering an error 682 * If this happens, diagnose-build-failure.sh should also identify which 683 file(s) specifically 684* The build is nondeterministic and/or affected by timestamps 685* The build via gradlew actually passes and this build failure is specific to 686 Android Studio 687 688Some more-specific build failures are listed below in this page. 689 690#### Out-of-date platform prebuilts 691 692Like a normal Android library developed in Android Studio, libraries within 693`androidx` are built against prebuilts of the platform SDK. These are checked in 694to the `prebuilts/fullsdk-darwin/platforms/<android-version>` directory. 695 696If you are developing against pre-release platform APIs in the internal 697`androidx-platform-dev` branch, you may need to update these prebuilts to obtain 698the latest API changes. 699 700#### Missing external dependency 701 702If Gradle cannot resolve a dependency listed in your `build.gradle`: 703 704* You will probably want to import the missing artifact via 705 [importMaven.sh](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:development/importMaven/README.md) 706 707 * We store artifacts in the prebuilts repositories under 708 `prebuilts/androidx` to facilitate reproducible builds even if remote 709 artifacts are changed. 710 711* You may need to [establish trust for](#dependency-verification) the new 712 artifact 713 714##### Importing dependencies in `libs.versions.toml` 715 716Libraries typically reference dependencies using constants defined in 717[`libs.versions.toml`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:gradle/libs.versions.toml). 718Update this file to include a constant for the version of the library that you 719want to depend on. You will reference this constant in your library's 720`build.gradle` dependencies. 721 722**After** you update the `libs.versions.toml` file with new dependencies, you 723can download them by running: 724 725```shell 726cd frameworks/support &&\ 727development/importMaven/importMaven.sh import-toml 728``` 729 730This command will resolve everything declared in the `libs.versions.toml` file 731and download missing artifacts into `prebuilts/androidx/external` or 732`prebuilts/androidx/internal`. 733 734Make sure to upload these changes before or concurrently (ex. in the same Gerrit 735topic) with the dependent library code. 736 737##### Downloading a dependency without changing `libs.versions.toml` 738 739You can also download a dependency without changing `libs.versions.toml` file by 740directly invoking: 741 742```shell 743cd frameworks/support &&\ 744./development/importMaven/importMaven.sh someGroupId:someArtifactId:someVersion 745``` 746 747##### Missing konan dependencies 748 749Kotlin Multiplatform projects need prebuilts to compile native code, which are 750located under `prebuilts/androidx/konan`. **After** you update the kotlin 751version of AndroidX, you should also download necessary prebuilts via: 752 753```shell 754cd frameworks/support &&\ 755development/importMaven/importMaven.sh import-konan-binaries --konan-compiler-version <new-kotlin-version> 756``` 757 758Please remember to commit changes in the `prebuilts/androidx/konan` repository. 759 760#### Dependency verification 761 762If you import a new dependency that is either unsigned or is signed with a new, 763unrecognized key, then you will need to add new dependency verification metadata 764to indicate to Gradle that this new dependency is trusted. See the instructions 765[here](https://android.googlesource.com/platform/frameworks/support/+/androidx-main/gradle/README.md) 766 767#### Updating an existing dependency 768 769If an older version of a dependency prebuilt was already checked in, please 770manually remove it within the same CL that adds the new prebuilt. You will also 771need to update `Dependencies.kt` to reflect the version change. 772 773#### My gradle build fails with "Cannot invoke method getURLs() on null object" 774 775You're using Java 9's javac, possibly because you ran envsetup.sh from the 776platform build or specified Java 9 as the global default Java compiler. For the 777former, you can simply open a new shell and avoid running envsetup.sh. For the 778latter, we recommend you set Java 8 as the default compiler using sudo 779update-java-alternatives; however, if you must use Java 9 as the default then 780you may alternatively set JAVA_HOME to the location of the Java 8 SDK. 781 782#### My gradle build fails with "error: cannot find symbol" after making framework-dependent changes. 783 784You probably need to update the prebuilt SDK used by the gradle build. If you 785are referencing new framework APIs, you will need to wait for the framework 786changes to land in an SDK build (or build it yourself) and then land in both 787prebuilts/fullsdk and prebuilts/sdk. See 788[Updating SDK prebuilts](/docs/playbook.md#prebuilts-fullsdk) 789for more information. 790 791#### How do I handle refactoring a framework API referenced from a library? 792 793Because AndroidX must compile against both the current framework and the latest 794SDK prebuilt, and because compiling the SDK prebuilt depends on AndroidX, you 795will need to refactor in stages: 796 7971. Remove references to the target APIs from AndroidX 7982. Perform the refactoring in the framework 7993. Update the framework prebuilt SDK to incorporate changes in (2) 8004. Add references to the refactored APIs in AndroidX 8015. Update AndroidX prebuilts to incorporate changes in (4) 802 803## Testing {#testing} 804 805AndroidX libraries are expected to include unit or integration test coverage for 806100% of their public API surface. Additionally, all CLs must include a `Test:` 807stanza indicating which tests were used to verify correctness. Any CLs 808implementing bug fixes are expected to include new regression tests specific to 809the issue being fixed. 810 811### Running tests {#run-tests} 812 813Generally, tests in the AndroidX repository should be run through the Android 814Studio UI. You can also run tests from the command line or via remote devices on 815FTL, see 816[Running unit and integration tests](/docs/testing.md#running) 817for details. 818 819#### Single test class or method 820 8211. Open the desired test file in Android Studio 8222. Right-click on a test class or `@Test` method name and select `Run <name>` 823 824#### Full test package 825 8261. In the `Project` side panel, open the desired module 8272. Find the package directory with the tests 8283. Right-click on the directory and select `Run <package>` 829 830### Running sample apps {#run-samples} 831 832The AndroidX repository has a set of Android applications that exercise AndroidX 833code. These applications can be useful when you want to debug a real running 834application, or reproduce a problem interactively, before writing test code. 835 836These applications are named either `<libraryname>-integration-tests-testapp`, 837or `support-\*-demos` (e.g. `support-v4-demos` or `support-leanback-demos`). You 838can run them by clicking `Run > Run ...` and choosing the desired application. 839 840See the [Testing](/docs/testing.md) page for more resources on 841writing, running, and monitoring tests. 842 843### AVD Manager 844 845The Android Studio instance started by `./studiow` uses a custom SDK directory, 846which means any virtual devices created by a "standard" non-AndroidX instance of 847Android Studio will be *visible* from the `./studiow` instance but will be 848unable to locate the SDK artifacts -- they will display a `Download` button. 849 850You can either use the `Download` button to download an extra copy of the SDK 851artifacts *or* you can set up a symlink to your "standard" non-AndroidX SDK 852directory to expose your existing artifacts to the `./studiow` instance: 853 854```shell 855# Using the default MacOS Android SDK directory... 856ln -s /Users/$(whoami)/Library/Android/sdk/system-images \ 857 ../../prebuilts/fullsdk-darwin/system-images 858``` 859 860## Library snapshots {#snapshots} 861 862### Quick how-to 863 864Add the following snippet to your build.gradle file, replacing `buildId` with a 865snapshot build ID. 866 867```groovy {highlight=context:[buildId]} 868allprojects { 869 repositories { 870 google() 871 jcenter() 872 maven { url 'https://androidx.dev/snapshots/builds/[buildId]/artifacts/repository' } 873 } 874} 875``` 876 877You must define dependencies on artifacts using the `SNAPSHOT` version suffix, 878for example: 879 880```groovy {highlight=context:SNAPSHOT} 881dependencies { 882 implementation "androidx.core:core:1.2.0-SNAPSHOT" 883} 884``` 885 886### Where to find snapshots 887 888If you want to use unreleased `SNAPSHOT` versions of `androidx` artifacts, you 889can find them on either our public-facing build server: 890 891`https://ci.android.com/builds/submitted/<build_id>/androidx_snapshot/latest` 892 893or on our slightly-more-convenient [androidx.dev](https://androidx.dev) site: 894 895`https://androidx.dev/snapshots/builds/<build-id>/artifacts` for a specific 896build ID 897 898`https://androidx.dev/snapshots/latest/artifacts` for tip-of-tree snapshots 899 900### Obtaining a build ID 901 902To browse build IDs, you can visit either 903[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?) 904on ci.android.com or [Snapshots](https://androidx.dev/snapshots/builds) on the 905androidx.dev site. 906 907Note that if you are using androidx.dev, you may substitute `latest` for a build 908ID to use the last known good build. 909 910To manually find the last known good `build-id`, you have several options. 911 912#### Snapshots on androidx.dev 913 914[Snapshots](https://androidx.dev/snapshots/builds) on androidx.dev only lists 915usable builds. 916 917#### Programmatically via `jq` 918 919Install `jq`: 920 921```shell 922sudo apt-get install jq 923``` 924 925```shell 926ID=`curl -s "https://ci.android.com/builds/branches/aosp-androidx-main/status.json" | jq ".targets[] | select(.ID==\"aosp-androidx-main.androidx_snapshot\") | .last_known_good_build"` \ 927 && echo https://ci.android.com/builds/submitted/"${ID:1:-1}"/androidx_snapshot/latest/raw/repository/ 928``` 929 930#### Android build server 931 932Go to 933[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?) 934on ci.android.com. 935 936For `androidx-snapshot` target, wait for the green "last known good build" 937button to load and then click it to follow it to the build artifact URL. 938 939### Using in a Gradle build 940 941To make these artifacts visible to Gradle, you need to add it as a repository: 942 943```groovy 944allprojects { 945 repositories { 946 google() 947 maven { 948 // For all Jetpack libraries (including Compose) 949 url 'https://androidx.dev/snapshots/builds/<build-id>/artifacts/repository' 950 } 951 } 952} 953``` 954 955Note that the above requires you to know the `build-id` of the snapshots you 956want. 957 958#### Specifying dependencies 959 960All artifacts in the snapshot repository are versioned as `x.y.z-SNAPSHOT`. So 961to use a snapshot artifact, the version in your `build.gradle` will need to be 962updated to `androidx.<groupId>:<artifactId>:X.Y.Z-SNAPSHOT` 963 964For example, to use the `core:core:1.2.0-SNAPSHOT` snapshot, you would add the 965following to your `build.gradle`: 966 967``` 968dependencies { 969 ... 970 implementation("androidx.core:core:1.2.0-SNAPSHOT") 971 ... 972} 973``` 974 975## FAQ {#faq} 976 977### How do I test my change in a separate Android Studio project? {#faq-test-change-studio} 978 979If you're working on a new feature or bug fix in AndroidX, you may want to test 980your changes against another project to verify that the change makes sense in a 981real-world context or that a bug's specific repro case has been fixed. 982 983If you need to be absolutely sure that your test will exactly emulate the 984developer's experience, you can repeatedly build the AndroidX archive and 985rebuild your application. In this case, you will need to create a local build of 986AndroidX's local Maven repository artifact and install it in your Android SDK 987path. 988 989First, use the `createArchive` Gradle task to generate the local Maven 990repository artifact: 991 992```shell 993# Creates <path-to-checkout>/out/repository/ 994./gradlew createArchive 995``` 996 997Using your alternate (non-AndroidX) version of Android Studio open the project's 998`settings.gradle.kts` and add the following within 999`dependencyResolutionManagement` to make your project look for binaries in the 1000newly built repository: 1001 1002```kotlin 1003dependencyResolutionManagement { 1004 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 1005 repositories { 1006 google() 1007 mavenCentral() 1008 // Add this 1009 maven { 1010 setUrl("<absolute-path-to-checkout>/out/repository/") 1011 } 1012 } 1013} 1014``` 1015 1016NOTE Gradle resolves dependencies in the order that the repositories are defined 1017(if 2 repositories can resolve the same dependency, the first listed will do so 1018and the second will not). Therefore, if the library you are testing has the same 1019group, artifact, and version as one already published, you will want to list 1020your custom maven repo first. 1021 1022Finally, in the dependencies section of your standalone project's `build.gradle` 1023file, add or update the `implementation` entries to reflect the AndroidX modules 1024that you would like to test. Example: 1025 1026``` 1027dependencies { 1028 ... 1029 implementation "androidx.appcompat:appcompat:1.0.0-alpha02" 1030} 1031``` 1032 1033If you are testing your changes in the Android Platform code, you can replace 1034the module you are testing 1035`YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository` with your own 1036module. We recommend only replacing the module you are modifying instead of the 1037full m2repository to avoid version issues of other modules. You can either take 1038the unzipped directory from 1039`<path-to-checkout>/out/dist/top-of-tree-m2repository-##.zip`, or from 1040`<path-to-checkout>/out/repository/` after building `androidx`. Here is an 1041example of replacing the RecyclerView module: 1042 1043```shell 1044$TARGET=YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07; 1045rm -rf $TARGET; 1046cp -a <path-to-sdk>/extras/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07 $TARGET 1047``` 1048 1049Make sure the library versions are the same before and after replacement. Then 1050you can build the Android platform code with the new `androidx` code. 1051 1052### How do I add content to a library's Overview reference doc page? 1053 1054Put content in a markdown file that ends with `-documentation.md` in the 1055directory that corresponds to the Overview page that you'd like to document. 1056 1057For example, the `androidx.compose.runtime` 1058[Overview page](https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary) 1059includes content from 1060[compose-runtime-documentation.md](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/compose-runtime-documentation.md). 1061 1062### How do I enable MultiDex for my library? 1063 1064It is enabled automatically as androidx minSdkVersion is API >=21. 1065