blob: 5715972087e304d52ec2eff5bdddef87e5bd3b39 [file] [log] [blame] [view]
AndroidX Core Team2e416b22020-12-03 22:58:07 +00001# 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](loaf.md) for details on developing and releasing
10a library, [API Guidelines](api_guidelines.md) for best practices regarding
11public APIs, or [Policies and Processes](policies.md) for an overview of the
12constraints placed on changes.
13
14## Workstation setup {#setup}
15
16You will need to install the `repo` tool, which is used for Git branch and
17commit management. If you want to learn more about `repo`, see the
18[Repo Command Reference](https://source.android.com/setup/develop/repo).
19
20### Linux and MacOS {#setup-linux-mac}
21
22First, download `repo` using `curl`.
23
24```shell
25test -d ~/bin || mkdir ~/bin
26curl https://storage.googleapis.com/git-repo-downloads/repo \
27 > ~/bin/repo && chmod 700 ~/bin/repo
28```
29
30Then, modify `~/.bash_profile` (if using `bash`) to ensure you can find local
31binaries from the command line.
32
33```shell
34export PATH=~/bin:$PATH
35```
36
37You will need to either start a new terminal session or run `source
38~/.bash_profile` to pick up the new path.
39
40If you encounter an SSL `CERTIFICATE_VERIFY_FAILED` error or warning about
41Python 2 being no longer supported, you will need to install Python 3 and alias
42your `repo` command to run with `python3`.
43
44```shell {.bad}
45repo: warning: Python 2 is no longer supported; Please upgrade to Python 3.6+.
46```
47
48```shell {.bad}
49Downloading Repo source from https://gerrit.googlesource.com/git-repo
50fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle
51fatal: error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
52```
53
54First, install Python 3 from the [official website](https://www.python.org).
55Please read the "Important Information" displayed during installation for
56information about SSL/TLS certificate validation and the running the "Install
57Certificates.command".
58
59Next, open your `~/.bash_profile` and add the following lines to wrap the `repo`
60command:
61
62```shell
63# Force repo to run with Python3
64function repo() {
65 command python3 "$(which repo)" $@
66}
67```
68
69### Windows {#setup-win}
70
71Sorry, Windows is not a supported platform for AndroidX development.
72
73## Set up access control {#access}
74
75### Authenticate to AOSP Gerrit {#access-gerrit}
76
77Before you can upload changes, you will need to associate your Google
78credentials with the AOSP Gerrit code review system by signing in to
79[android-review.googlesource.com](https://android-review.googlesource.com) at
80least once using the account you will use to submit patches.
81
82Next, you will need to
83[set up authentication](https://android-review.googlesource.com/new-password).
84This will give you a shell command to update your local Git cookies, which will
85allow you to upload changes.
86
87Finally, you will need to accept the
88[CLA for new contributors](https://android-review.googlesource.com/settings/new-agreement).
89
90## Check out the source {#source}
91
92Like ChromeOS, Chromium, and the Android build system, we develop in the open as
93much as possible. All feature development occurs in the public
AndroidX Core Team408c27b2020-12-15 15:57:00 +000094[androidx-main](https://android.googlesource.com/platform/frameworks/support/+/androidx-main)
AndroidX Core Team2e416b22020-12-03 22:58:07 +000095branch of the Android Open Source Project.
96
97As of 2020/03/20, you will need about 38 GB for a fully-built checkout.
98
99### Synchronize the branch {#source-checkout}
100
101Use the following `repo` commands to check out your branch.
102
AndroidX Core Teamf5f77ab2021-01-05 10:56:15 -0500103#### Public main development branch {#androidx-main}
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000104
105All development should occur in this branch unless otherwise specified by the
106AndroidX Core team.
107
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000108The following command will check out the public main development branch:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000109
110```shell
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000111mkdir androidx-main && cd androidx-main
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000112repo init -u https://android.googlesource.com/platform/manifest \
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000113 -b androidx-main --partial-clone --clone-filter=blob:limit=10M
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000114repo sync -c -j8
115```
116
117NOTE On MacOS, if you receive an SSL error like `SSL: CERTIFICATE_VERIFY_FAILED`
118you may need to install Python3 and boot strap the SSL certificates in the
119included version of pip. You can execute `Install Certificates.command` under
120`/Applications/Python 3.6/` to do so.
121
122### Increase Git rename limit {#source-config}
123
124To ensure `git` can detect diffs and renames across significant changes (namely,
125the `androidx.*` package rename), we recommend that you set the following `git
126config` properties:
127
128```shell
129git config --global merge.renameLimit 999999
130git config --global diff.renameLimit 999999
131```
132
133## Explore source code from a browser {#code-search}
134
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000135`androidx-main` has a publicly-accessible
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000136[code search](https://cs.android.com/androidx/platform/frameworks/support) that
137allows you to explore all of the source code in the repository. Links to this
AndroidX Core Team37584142021-02-25 17:58:46 +0000138URL may be shared on the public issue tracked and other external sites.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000139
140We recommend setting up a custom search engine in Chrome as a faster (and
141publicly-accessible) alternative to `cs/`.
142
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000143### Custom search engine for `androidx-main` {#custom-search-engine}
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000144
1451. Open `chrome://settings/searchEngines`
1461. Click the `Add` button
1471. Enter a name for your search engine, ex. "AndroidX Code Search"
1481. Enter a keyword, ex. "csa"
1491. Enter the following URL:
150 `https://cs.android.com/search?q=%s&ss=androidx%2Fplatform%2Fframeworks%2Fsupport`
1511. Click the `Add` button
152
153Now you can select the Chrome omnibox, type in `csa` and press tab, then enter a
154query to search for, e.g. `AppCompatButton file:appcompat`, and press the
155`Enter` key to get to the search result page.
156
157## Develop in Android Studio {#studio}
158
159Library development uses a curated version of Android Studio to ensure
160compatibility between various components of the development workflow.
161
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000162From the `frameworks/support` directory, you can use `./studiow m` (short for
163`ANDROIDX_PROJECTS=main ./gradlew studio`) to automatically download and run the
164correct version of Studio to work on the `main` set of androidx projects.
165[studiow](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:studiow)
166also supports several other arguments like `all` for other subsets of the
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000167projects.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000168
169Next, open the `framework/support` project root from your checkout. If Studio
170asks you which SDK you would like to use, select `Use project SDK`. Importing
171projects may take a while, but once that finishes you can use Studio as you
172normally would for application or library development -- right-click on a test
173or sample to run or debug it, search through classes, and so on.
174
175If you see any errors (red underlines), click Gradle's elephant button in the
176toolbar ("Sync Project with Gradle Files") and they should resolve once the
177build completes.
178
179> NOTE: You should choose "Use project SDK" when prompted by Studio. If you
180> picked "Android Studio SDK" by mistake, don't panic! You can fix this by
181> opening `File > Project Structure > Platform Settings > SDKs` and manually
182> setting the Android SDK home path to
183> `<project-root>/prebuilts/fullsdk-<platform>`.
184
185> NOTE: If Android Studio's UI looks scaled up, ex. twice the size it should be,
186> you may need to add the following line to your `studio64.vmoptions` file using
187> `Help -> Edit Custom VM Options`:
188>
189> ```
190> -Dsun.java2d.uiScale.enabled=false
191> ```
192
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000193If in the future you encounter unexpected errors in Studio and you want to check
194for the possibility it is due to some incorrect settings or other generated
195files, you can run `./studiow --clean main <project subset>` or `./studiow
196--reinstall <project subset>` to clean generated files or reinstall Studio.
197
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000198## Making changes {#changes}
199
AndroidX Core Team5c914c42021-02-08 17:22:57 +0000200Similar to Android framework development, library development should occur in
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000201CL-specific working branches. Use `repo` to create, upload, and abandon local
202branches. Use `git` to manage changes within a local branch.
203
204```shell
205cd path/to/checkout/frameworks/support/
206repo start my_branch_name .
207# make necessary code changes
208# use git to commit changes
209repo upload --cbr -t .
210```
211
212The `--cbr` switch automatically picks the current repo branch for upload. The
213`-t` switch sets the Gerrit topic to the branch name, e.g. `my-branch-name`.
214
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000215NOTE If you encounter issues with `repo upload`, consider running upload with
216trace enabled, e.g. `GIT_DAPPER_TRACE=1 repo --trace upload . --cbr -y`. These
217logs can be helpful for reporting issues to the team that manages our git
218servers.
219
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000220NOTE If `repo upload` or any `git` command hangs and causes your CPU usage to
221skyrocket (e.g. your laptop fan sounds like a jet engine), then you may be
222hitting a rare issue with Git-on-Borg and HTTP/2. You can force `git` and `repo`
223to use HTTP/1.1 with `git config --global http.version HTTP/1.1`.
224
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000225## Building {#building}
226
227### Modules and Maven artifacts {#modules-and-maven-artifacts}
228
229To build a specific module, use the module's `assemble` Gradle task. For
230example, if you are working on `core` module use:
231
232```shell
233./gradlew core:core:assemble
234```
235
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000236To make warnings fail your build (same as presubmit), use the `--strict` flag,
237which our gradlew expands into a few correctness-related flags including
238`-Pandroidx.allWarningsAsErrors`:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000239
240```shell
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000241./gradlew core:core:assemble --strict
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000242```
243
244To build every module, run the Lint verifier, verify the public API surface, and
245generate the local Maven repository artifact, use the `createArchive` Gradle
246task:
247
248```shell
249./gradlew createArchive
250```
251
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000252To run the complete build task that our build servers use, use the corresponding
253shell script:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000254
255```shell
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000256./busytown/androidx.sh
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000257```
258
259### Attaching a debugger to the build
260
261Gradle tasks, including building a module, may be run or debugged from Android
262Studio's `Gradle` pane by finding the task to be debugged -- for example,
263`androidx > androidx > appcompat > appcompat > build > assemble` --
264right-clicking on it, and then selecting `Debug...`.
265
266Note that debugging will not be available until Gradle sync has completed.
267
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000268#### From the command line
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000269
270Tasks may also be debugged from the command line, which may be useful if
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000271`./studiow` cannot run due to a Gradle task configuration issue.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000272
2731. From the configurations dropdown in Studio, select "Edit Configurations".
2741. Click the plus in the top left to create a new "Remote" configuration. Give
275 it a name and hit "Ok".
2761. Set breakpoints.
2771. Run your task with added flags: `./gradlew <your_task_here>
278 -Dorg.gradle.debug=true --no-daemon`
2791. Hit the "Debug" button to the right of the configuration dropdown to attach
280 to the process.
281
282#### Troubleshooting the debugger
283
284If you get a "Connection refused" error, it's likely because a gradle daemon is
285still running on the port specified in the config, and you can fix this by
286killing the running gradle daemons:
287
288```shell
289./gradlew --stop
290```
291
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000292NOTE This is described in more detail in this
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000293[Medium article](https://medium.com/grandcentrix/how-to-debug-gradle-plugins-with-intellij-eef2ef681a7b).
294
295#### Attaching to an annotation processor
296
297Annotation processors run as part of the build, to debug them is similar to
298debugging the build.
299
300For a Java project:
301
302```shell
303./gradlew <your_project>:compileDebugJava --no-daemon --rerun-tasks -Dorg.gradle.debug=true
304```
305
306For a Kotlin project:
307
308```shell
309./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"
310```
311
312### Optional: Enabling internal menu in IntelliJ/Studio
313
314To enable tools such as `PSI tree` inside of IntelliJ/Studio to help debug
315Android Lint checks and Metalava, you can enable the
316[internal menu](https://www.jetbrains.org/intellij/sdk/docs/reference_guide/internal_actions/enabling_internal.html)
317which is typically used for plugin and IDE development.
318
319### Reference documentation {#docs}
320
321Our reference docs (Javadocs and KotlinDocs) are published to
322https://developer.android.com/reference/androidx/packages and may be built
323locally.
324
325NOTE `./gradlew tasks` always has the canonical task information! When in doubt,
326run `./gradlew tasks`
327
328#### Javadocs
329
330To build API reference docs for tip-of-tree Java source code, run the Gradle
331task:
332
333```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000334./gradlew doclavaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000335```
336
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000337To generate offline docs use '-PofflineDocs=true' parameter. Places the
338documentation in
339`{androidx-main}/out/dist/out/androidx/docs-tip-of-tree/build/javadoc`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000340
341#### KotlinDocs
342
343To build API reference docs for tip-of-tree Kotlin source code, run the Gradle
344task:
345
346```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000347./gradlew dokkaKotlinDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000348```
349
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000350Places the documentation in
351`{androidx-main}/out/dist/out/androidx/docs-tip-of-tree/build/dokkaKotlinDocs`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000352
353#### Release docs
354
355To build API reference docs for published artifacts formatted for use on
356[d.android.com](http://d.android.com), run the Gradle command:
357
358```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000359./gradlew zipDoclavaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000360```
361
362This will create the artifact
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000363`{androidx-main}/out/dist/doclava-public-docs-0.zip`. This command builds docs
364based on the version specified in
365`{androidx-main-checkout}/frameworks/support/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000366and uses the prebuilt checked into
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000367`{androidx-main-checkout}/prebuilts/androidx/internal/androidx/`. We
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000368colloquially refer to this two step process of (1) updating
369`PublishDocsRules.kt` and (2) checking in a prebuilt artifact into the prebuilts
370directory as [The Prebuilts Dance](releasing_detailed.md#the-prebuilts-danceâ„¢).
371So, to build javadocs that will be published to
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000372https://developer.android.com/reference/androidx/packages, both of these steps
373need to be completed.
374
375Once you done the above steps, Kotlin docs will also be generated, with the only
376difference being that we use the Gradle command:
377
378```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000379./gradlew zipDokkaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000380```
381
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000382This will create the artifact `{androidx-main}/out/dist/dokka-public-docs-0.zip`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000383
384### Updating public APIs {#updating-public-apis}
385
386Public API tasks -- including tracking, linting, and verifying compatibility --
387are run under the following conditions based on the `androidx` configuration
388block, evaluated in order:
389
390* `runApiTasks=Yes` => yes
391* `runApiTasks=No` => no
392* `toolingProject=true` => no
393* `mavenVersion` or group version not set => no
394* Has an existing `api/` directory => yes
395* `publish=SNAPSHOT_AND_RELEASE` => yes
396* Otherwise, no
397
398If you make changes to tracked public APIs, you will need to acknowledge the
399changes by updating the `<component>/api/current.txt` and associated API files.
400This is handled automatically by the `updateApi` Gradle task:
401
402```shell
403# Run updateApi for all modules.
404./gradlew updateApi
405
406# Run updateApi for a single module, ex. appcompat-resources in group appcompat.
407./gradlew :appcompat:appcompat-resources:updateApi
408```
409
410If you change the public APIs without updating the API file, your module will
411still build **but** your CL will fail Treehugger presubmit checks.
412
413### Release notes & the `Relnote:` tag {#relnote}
414
415Prior to releasing, release notes are pre-populated using a script and placed
416into a Google Doc. The Google Doc is manually double checked by library owners
417before the release goes live. To auto-populate your release notes, you can use
418the semi-optional commit tag `Relnote:` in your commit, which will automatically
419include that message the commit in the pre-populated release notes.
420
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000421The presence of a `Relnote:` tag is required for API changes in `androidx-main`.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000422
423#### How to use it?
424
425One-line release note:
426
427``` {.good}
428Relnote: Fixed a critical bug
429```
430
431``` {.good}
432Relnote: "Fixed a critical bug"
433```
434
435``` {.good}
436Relnote: Added the following string function: `myFoo(\"bar\")`
437```
438
439Multi-line release note:
440
441Note: If the following lines do not contain an indent, you may hit b/165570183.
442
443``` {.good}
444Relnote: "We're launching this awesome new feature! It solves a whole list of
445 problems that require a lot of explaining! "
446```
447
448``` {.good}
449Relnote: """Added the following string function: `myFoo("bar")`
450 It will fix cases where you have to call `myFoo("baz").myBar("bar")`
451 """
452```
453
454Opt out of the Relnote tag:
455
456``` {.good}
457Relnote: N/A
458```
459
460``` {.good}
461Relnote: NA
462```
463
464NOT VALID:
465
466``` {.bad}
467Relnote: This is an INVALID multi-line release note. Our current scripts won't
468include anything beyond the first line. The script has no way of knowing when
469the release note actually stops.
470```
471
472``` {.bad}
473Relnote: This is an INVALID multi-line release note. "Quotes" need to be
474 escaped in order for them to be parsed properly.
475```
476
477### Common build errors
478
479#### Diagnosing build failures
480
481If you've encountered a build failure and you're not sure what is triggering it,
482then please run
483`./development/diagnose-build-failure/diagnose-build-failure.sh`.
484
485This script can categorize your build failure into one of the following
486categories:
487
488* The Gradle Daemon is saving state in memory and triggering a failure
489* Your source files have been changed and/or incompatible git commits have
490 been checked out
491* Some file in the out/ dir is triggering an error
492 * If this happens, diagnose-build-failure.sh should also identify which
493 file(s) specifically
494* The build is nondeterministic and/or affected by timestamps
495* The build via gradlew actually passes and this build failure is specific to
496 Android Studio
497
498Some more-specific build failures are listed below in this page.
499
500#### Out-of-date platform prebuilts
501
502Like a normal Android library developed in Android Studio, libraries within
503`androidx` are built against prebuilts of the platform SDK. These are checked in
504to the `prebuilts/fullsdk-darwin/platforms/<android-version>` directory.
505
506If you are developing against pre-release platform APIs in the internal
507`androidx-platform-dev` branch, you may need to update these prebuilts to obtain
508the latest API changes.
509
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000510#### Missing external dependency
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000511
512If Gradle cannot resolve a dependency listed in your `build.gradle`, you may
513need to import the corresponding artifact into `prebuilts/androidx/external`.
514Our workflow does not automatically download artifacts from the internet to
515facilitate reproducible builds even if remote artifacts are changed.
516
517You can download a dependency by running:
518
519```shell
520cd frameworks/support && ./development/importMaven/import_maven_artifacts.py -n 'someGroupId:someArtifactId:someVersion'
521```
522
523This will create a change within the `prebuilts/androidx/external` directory.
524Make sure to upload this change before or concurrently (ex. in the same Gerrit
525topic) with the dependent library code.
526
527Libraries typically reference dependencies using constants defined in
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000528[`Dependencies.kt`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt),
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000529so please update this file to include a constant for the version of the library
530that you have checked in. You will reference this constant in your library's
531`build.gradle` dependencies.
532
533#### Updating an existing dependency
534
535If an older version of a dependency prebuilt was already checked in, please
536manually remove it within the same CL that adds the new prebuilt. You will also
537need to update `Dependencies.kt` to reflect the version change.
538
539#### My gradle build fails with "Cannot invoke method getURLs() on null object"
540
541You're using Java 9's javac, possibly because you ran envsetup.sh from the
542platform build or specified Java 9 as the global default Java compiler. For the
543former, you can simply open a new shell and avoid running envsetup.sh. For the
544latter, we recommend you set Java 8 as the default compiler using sudo
545update-java-alternatives; however, if you must use Java 9 as the default then
546you may alternatively set JAVA_HOME to the location of the Java 8 SDK.
547
548#### My gradle build fails with "error: cannot find symbol" after making framework-dependent changes.
549
550You probably need to update the prebuilt SDK used by the gradle build. If you
551are referencing new framework APIs, you will need to wait for the framework
552changes to land in an SDK build (or build it yourself) and then land in both
553prebuilts/fullsdk and prebuilts/sdk. See
554[Updating SDK prebuilts](playbook.md#prebuilts-fullsdk) for more information.
555
556#### How do I handle refactoring a framework API referenced from a library?
557
558Because AndroidX must compile against both the current framework and the latest
559SDK prebuilt, and because compiling the SDK prebuilt depends on AndroidX, you
560will need to refactor in stages: Remove references to the target APIs from
561AndroidX Perform the refactoring in the framework Update the framework prebuilt
562SDK to incorporate changes in (2) Add references to the refactored APIs in
563AndroidX Update AndroidX prebuilts to incorporate changes in (4)
564
565## Testing {#testing}
566
567AndroidX libraries are expected to include unit or integration test coverage for
568100% of their public API surface. Additionally, all CLs must include a `Test:`
569stanza indicating which tests were used to verify correctness. Any CLs
570implementing bug fixes are expected to include new regression tests specific to
571the issue being fixed
572
573See the [Testing](testing.md) page for more resources on writing, running, and
574monitoring tests.
575
576### AVD Manager
577
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000578The Android Studio instance started by `./studiow` uses a custom SDK directory,
579which means any virtual devices created by a "standard" non-AndroidX instance of
580Android Studio will be _visible_ from the `./studiow` instance but will be
581unable to locate the SDK artifacts -- they will display a `Download` button.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000582
583You can either use the `Download` button to download an extra copy of the SDK
584artifacts _or_ you can set up a symlink to your "standard" non-AndroidX SDK
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000585directory to expose your existing artifacts to the `./studiow` instance:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000586
587```shell
588# Using the default MacOS Android SDK directory...
589ln -s /Users/$(whoami)/Library/Android/sdk/system-images \
590 ../../prebuilts/fullsdk-darwin/system-images
591```
592
593### Benchmarking {#testing-benchmarking}
594
595Libraries are encouraged to write and monitor performance benchmarks. See the
596[Benchmarking](benchmarking.md) page for more details.
597
598## Library snapshots {#snapshots}
599
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000600### Quick how-to
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000601
602Add the following snippet to your build.gradle file, replacing `buildId` with a
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000603snapshot build ID.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000604
605```groovy {highlight=context:[buildId]}
606allprojects {
607 repositories {
608 google()
609 jcenter()
610 maven { url 'https://androidx.dev/snapshots/builds/[buildId]/artifacts/repository' }
611 }
612}
613```
614
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000615You must define dependencies on artifacts using the `SNAPSHOT` version suffix,
616for example:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000617
618```groovy {highlight=context:SNAPSHOT}
619dependencies {
620 implementation "androidx.core:core:1.2.0-SNAPSHOT"
621}
622```
623
624### Where to find snapshots
625
626If you want to use unreleased `SNAPSHOT` versions of `androidx` artifacts, you
627can find them on either our public-facing build server:
628
629`https://ci.android.com/builds/submitted/<build_id>/androidx_snapshot/latest`
630
631or on our slightly-more-convenient [androidx.dev](https://androidx.dev) site:
632
633`https://androidx.dev/snapshots/builds/<build-id>/artifacts/repository` for a
634specific build ID
635
636`https://androidx.dev/snapshots/builds/latest/artifacts/repository` for
637tip-of-tree snapshots
638
639### Obtaining a build ID
640
641To browse build IDs, you can visit either
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000642[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?)
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000643on ci.android.com or [Snapshots](https://androidx.dev/snapshots/builds) on the
644androidx.dev site.
645
646Note that if you are using androidx.dev, you may substitute `latest` for a build
647ID to use the last known good build.
648
649To manually find the last known good `build-id`, you have several options.
650
651#### Snapshots on androidx.dev
652
653[Snapshots](https://androidx.dev/snapshots/builds) on androidx.dev only lists
654usable builds.
655
656#### Programmatically via `jq`
657
658Install `jq`:
659
660```shell
661sudo apt-get install jq
662```
663
664```shell
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000665ID=`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"` \
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000666 && echo https://ci.android.com/builds/submitted/"${ID:1:-1}"/androidx_snapshot/latest/raw/repository/
667```
668
669#### Android build server
670
671Go to
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000672[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?)
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000673on ci.android.com.
674
675For `androidx-snapshot` target, wait for the green "last known good build"
676button to load and then click it to follow it to the build artifact URL.
677
678### Using in a Gradle build
679
680To make these artifacts visible to Gradle, you need to add it as a respository:
681
682```groovy
683allprojects {
684 repositories {
685 google()
686 maven {
687 // For all Jetpack libraries (including Compose)
688 url 'https://androidx.dev/snapshots/builds/<build-id>/artifacts/repository'
689 }
690 }
691}
692```
693
694Note that the above requires you to know the `build-id` of the snapshots you
695want.
696
697#### Specifying dependencies
698
699All artifacts in the snapshot repository are versioned as `x.y.z-SNAPSHOT`. So
700to use a snapshot artifact, the version in your `build.gradle` will need to be
701updated to `androidx.<groupId>:<artifactId>:X.Y.Z-SNAPSHOT`
702
703For example, to use the `core:core:1.2.0-SHAPSHOT` snapshot, you would add the
704following to your `build.gradle`:
705
706```
707dependencies {
708 ...
709 implementation("androidx.core:core:1.2.0-SNAPSHOT")
710 ...
711}
712```
713
714## FAQ {#faq}
715
716### How do I test my change in a separate Android Studio project? {#faq-test-change-studio}
717
718If you're working on a new feature or bug fix in AndroidX, you may want to test
719your changes against another project to verify that the change makes sense in a
720real-world context or that a bug's specific repro case has been fixed.
721
722If you need to be absolutely sure that your test will exactly emulate the
723developer's experience, you can repeatedly build the AndroidX archive and
724rebuild your application. In this case, you will need to create a local build of
725AndroidX's local Maven repository artifact and install it in your Android SDK
726path.
727
728First, use the `createArchive` Gradle task to generate the local Maven
729repository artifact:
730
731```shell
732# Creates <path-to-checkout>/out/dist/sdk-repo-linux-m2repository-##.zip
733./gradlew createArchive
734```
735
736Next, take the ZIP output from this task and extract the contents to the Android
737SDK path that you are using for your alternate (non-AndroidX) version of Android
738Studio. For example, you may be using `~/Android/SDK/extras` if you are using
739the default Android Studio SDK for app development or
740`prebuilts/fullsdk-linux/extras` if you are using fullsdk for platform
741development.
742
743```shell
744# Creates or overwrites android/m2repository
745cd <path-to-sdk>/extras
746unzip <path-to-checkout>/out/dist/top-of-tree-m2repository-##.zip
747```
748
749In the project's 'build.gradle' within 'repositories' notify studio of the
750location of m2repository:
751
752```groovy
753allprojects {
754 repositories {
755 ...
756 maven {
757 url "<path-to-sdk>/extras/m2repository"
758 }
759 }
760}
761```
762
763NOTE Gradle resolves dependencies in the order that the repositories are defined
764(if 2 repositories can resolve the same dependency, the first listed will do so
765and the second will not). Therefore, if the library you are testing has the same
766group, artifact, and version as one already published, you will want to list
767your custom maven repo first.
768
769Finally, in the dependencies section of your standalone project's `build.gradle`
770file, add or update the `implementation` entries to reflect the AndroidX modules
771that you would like to test. Example:
772
773```
774dependencies {
775 ...
776 implementation "androidx.appcompat:appcompat::1.0.0-alpha02"
777}
778```
779
780If you are testing your changes in the Android Platform code, you can replace
781the module you are testing
782`YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository` with your own
783module. We recommend only replacing the module you are modifying instead of the
784full m2repository to avoid version issues of other modules. You can either take
785the unzipped directory from
786`<path-to-checkout>/out/dist/top-of-tree-m2repository-##.zip`, or from
787`<path-to-checkout>/out/androidx/build/support_repo/` after buiding `androidx`.
788Here is an example of replacing the RecyclerView module:
789
790```shell
791$TARGET=YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07;
792rm -rf $TARGET;
793cp -a <path-to-sdk>/extras/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07 $TARGET
794```
795
796Make sure the library versions are the same before and after replacement. Then
797you can build the Android platform code with the new `androidx` code.