blob: 933a00c785e324d98c9bd6f4e4bce16a966c7097 [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
AndroidX Core Team9e6c2362021-08-30 12:22:59 -070011public APIs and an overview of the constraints placed on changes.
AndroidX Core Team2e416b22020-12-03 22:58:07 +000012
13## Workstation setup {#setup}
14
AndroidX Core Team0db91f02021-05-06 22:45:18 +000015You will need to install the
16[`repo`](https://source.android.com/setup/develop#repo) tool, which is used for
17Git branch and commit management. If you want to learn more about `repo`, see
18the [Repo Command Reference](https://source.android.com/setup/develop/repo).
AndroidX Core Team2e416b22020-12-03 22:58:07 +000019
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
AndroidX Core Team685fbcd2022-01-10 14:18:55 -080030Then, modify `~/.zshrc` (or `~/.bash_profile` if using `bash`) to ensure you can
AndroidX Core Team21ccf652022-04-01 14:53:07 +000031find local binaries from the command line. We assume you're using `zsh`, but the
AndroidX Core Team685fbcd2022-01-10 14:18:55 -080032following should work with `bash` as well.
AndroidX Core Team2e416b22020-12-03 22:58:07 +000033
34```shell
35export PATH=~/bin:$PATH
36```
37
AndroidX Core Team685fbcd2022-01-10 14:18:55 -080038You will need to either start a new terminal session or run `source ~/.zshrc`
AndroidX Core Team21ccf652022-04-01 14:53:07 +000039(or `source ~/.bash_profile` if using `bash`) to pick up the new path.
AndroidX Core Team2e416b22020-12-03 22:58:07 +000040
41If you encounter an SSL `CERTIFICATE_VERIFY_FAILED` error or warning about
42Python 2 being no longer supported, you will need to install Python 3 and alias
43your `repo` command to run with `python3`.
44
45```shell {.bad}
46repo: warning: Python 2 is no longer supported; Please upgrade to Python 3.6+.
47```
48
49```shell {.bad}
50Downloading Repo source from https://gerrit.googlesource.com/git-repo
51fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle
52fatal: error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
53```
54
55First, install Python 3 from the [official website](https://www.python.org).
56Please read the "Important Information" displayed during installation for
57information about SSL/TLS certificate validation and the running the "Install
58Certificates.command".
59
AndroidX Core Team21ccf652022-04-01 14:53:07 +000060Next, double-check where your `repo
AndroidX Core Team685fbcd2022-01-10 14:18:55 -080061Next, open your `~/.zshrc` (or `~/.bash_profile` if using bash) and add the
62following lines to wrap the `repo` command:
AndroidX Core Team2e416b22020-12-03 22:58:07 +000063
64```shell
65# Force repo to run with Python3
66function repo() {
AndroidX Core Team21ccf652022-04-01 14:53:07 +000067 command python3 ~/bin/repo $@
AndroidX Core Team2e416b22020-12-03 22:58:07 +000068}
69```
70
AndroidX Core Team21ccf652022-04-01 14:53:07 +000071Make sure to reload the updated profile by starting a new terminal session or
72running `source ~/.zshrc` or `source ~/.bash_profile` as appropriate.
73
AndroidX Core Team2e416b22020-12-03 22:58:07 +000074### Windows {#setup-win}
75
76Sorry, Windows is not a supported platform for AndroidX development.
77
78## Set up access control {#access}
79
80### Authenticate to AOSP Gerrit {#access-gerrit}
81
82Before you can upload changes, you will need to associate your Google
83credentials with the AOSP Gerrit code review system by signing in to
84[android-review.googlesource.com](https://android-review.googlesource.com) at
85least once using the account you will use to submit patches.
86
87Next, you will need to
88[set up authentication](https://android-review.googlesource.com/new-password).
89This will give you a shell command to update your local Git cookies, which will
90allow you to upload changes.
91
92Finally, you will need to accept the
93[CLA for new contributors](https://android-review.googlesource.com/settings/new-agreement).
94
95## Check out the source {#source}
96
97Like ChromeOS, Chromium, and the Android build system, we develop in the open as
98much as possible. All feature development occurs in the public
AndroidX Core Team408c27b2020-12-15 15:57:00 +000099[androidx-main](https://android.googlesource.com/platform/frameworks/support/+/androidx-main)
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000100branch of the Android Open Source Project.
101
102As of 2020/03/20, you will need about 38 GB for a fully-built checkout.
103
104### Synchronize the branch {#source-checkout}
105
AndroidX Core Team4e1909a2021-10-20 15:04:04 +0000106Use the following commands to check out your branch.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000107
AndroidX Core Teamf5f77ab2021-01-05 10:56:15 -0500108#### Public main development branch {#androidx-main}
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000109
110All development should occur in this branch unless otherwise specified by the
111AndroidX Core team.
112
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000113The following command will check out the public main development branch:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000114
115```shell
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000116mkdir androidx-main && cd androidx-main
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000117repo init -u https://android.googlesource.com/platform/manifest \
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000118 -b androidx-main --partial-clone --clone-filter=blob:limit=10M
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000119repo sync -c -j8
120```
121
122NOTE On MacOS, if you receive an SSL error like `SSL: CERTIFICATE_VERIFY_FAILED`
123you may need to install Python3 and boot strap the SSL certificates in the
124included version of pip. You can execute `Install Certificates.command` under
125`/Applications/Python 3.6/` to do so.
126
127### Increase Git rename limit {#source-config}
128
129To ensure `git` can detect diffs and renames across significant changes (namely,
130the `androidx.*` package rename), we recommend that you set the following `git
131config` properties:
132
133```shell
134git config --global merge.renameLimit 999999
135git config --global diff.renameLimit 999999
136```
137
AndroidX Core Teamc2e3ad52021-08-17 13:40:01 -0400138### To check out older source, use the superproject
139
140The
141[git superproject](https://android.googlesource.com/platform/superproject/+/androidx-main)
142contains a history of the matching exact commits of each git repository over
143time, and it can be
144[checked out directly via git](https://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules)
145
alanve9101e42022-01-28 12:05:11 -0800146### Troubleshooting
147
148> NOTE: If the repo manifest changes -- for example when we update the version
149> of `platform-tools` by pointing it to a different git project -- you may see
150> the following error during`repo sync`:
151>
152> ```shell
153> error.GitError: Cannot fetch --force-sync not enabled; cannot overwrite a local work tree.
154> ...
155> error: Unable to fully sync the tree.
156> error: Downloading network changes failed.
157> ```
158>
159> This indicates that Studio or some other process has made changes in the git
160> project that has been replaced or removed. You can force `repo sync` to
161> discard these changes and check out the correct git project by adding the
162> `--force-sync` argument:
163>
164> ```shell
165> repo sync -j32 --force-sync
166> ```
167
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000168## Explore source code from a browser {#code-search}
169
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000170`androidx-main` has a publicly-accessible
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000171[code search](https://cs.android.com/androidx/platform/frameworks/support) that
172allows you to explore all of the source code in the repository. Links to this
AndroidX Core Team37584142021-02-25 17:58:46 +0000173URL may be shared on the public issue tracked and other external sites.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000174
175We recommend setting up a custom search engine in Chrome as a faster (and
176publicly-accessible) alternative to `cs/`.
177
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000178### Custom search engine for `androidx-main` {#custom-search-engine}
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000179
1801. Open `chrome://settings/searchEngines`
1811. Click the `Add` button
1821. Enter a name for your search engine, ex. "AndroidX Code Search"
1831. Enter a keyword, ex. "csa"
1841. Enter the following URL:
185 `https://cs.android.com/search?q=%s&ss=androidx%2Fplatform%2Fframeworks%2Fsupport`
1861. Click the `Add` button
187
188Now you can select the Chrome omnibox, type in `csa` and press tab, then enter a
189query to search for, e.g. `AppCompatButton file:appcompat`, and press the
190`Enter` key to get to the search result page.
191
192## Develop in Android Studio {#studio}
193
194Library development uses a curated version of Android Studio to ensure
195compatibility between various components of the development workflow.
196
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000197From the `frameworks/support` directory, you can use `./studiow m` (short for
198`ANDROIDX_PROJECTS=main ./gradlew studio`) to automatically download and run the
AndroidX Core Team23c50442021-05-18 13:03:40 -0400199correct version of Studio to work on the `main` set of androidx projects
200(non-Compose Jetpack libraries).
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000201[studiow](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:studiow)
202also supports several other arguments like `all` for other subsets of the
AndroidX Core Team23c50442021-05-18 13:03:40 -0400203projects (run `./studiow` for help).
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000204
205Next, open the `framework/support` project root from your checkout. If Studio
206asks you which SDK you would like to use, select `Use project SDK`. Importing
207projects may take a while, but once that finishes you can use Studio as you
208normally would for application or library development -- right-click on a test
209or sample to run or debug it, search through classes, and so on.
210
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000211If you get a “Unregistered VCS root detected” message, click “Add root” to
212enable the Git/VCS integration for Android Studio.
213
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000214If you see any errors (red underlines), click Gradle's elephant button in the
215toolbar ("Sync Project with Gradle Files") and they should resolve once the
216build completes.
217
218> NOTE: You should choose "Use project SDK" when prompted by Studio. If you
219> picked "Android Studio SDK" by mistake, don't panic! You can fix this by
220> opening `File > Project Structure > Platform Settings > SDKs` and manually
221> setting the Android SDK home path to
222> `<project-root>/prebuilts/fullsdk-<platform>`.
223
224> NOTE: If Android Studio's UI looks scaled up, ex. twice the size it should be,
225> you may need to add the following line to your `studio64.vmoptions` file using
226> `Help -> Edit Custom VM Options`:
227>
228> ```
229> -Dsun.java2d.uiScale.enabled=false
230> ```
231
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000232If in the future you encounter unexpected errors in Studio and you want to check
233for the possibility it is due to some incorrect settings or other generated
234files, you can run `./studiow --clean main <project subset>` or `./studiow
235--reinstall <project subset>` to clean generated files or reinstall Studio.
236
AndroidX Core Teame80aab72021-09-29 08:44:33 -0700237> Tip: If you don't see a specific Gradle task listed in Studio's Gradle pane,
238> check the following:
239>
240> * Studio might be running a different project subset than the one intended.
241> For example, `./studiow main` only loads the `main` set of androidx
242> projects; run `./studiow compose` to load the tasks specific to Compose.
243>
244> * Gradle tasks aren't being loaded. Under Studio's settings => Experimental,
245> make sure that "Do not build Gradle task list during Gradle sync" is
246> unchecked. (Note that unchecking this can reduce Studio's performance)
247
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000248## Making changes {#changes}
249
AndroidX Core Team5c914c42021-02-08 17:22:57 +0000250Similar to Android framework development, library development should occur in
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000251CL-specific working branches. Use `repo` to create, upload, and abandon local
252branches. Use `git` to manage changes within a local branch.
253
254```shell
255cd path/to/checkout/frameworks/support/
256repo start my_branch_name .
257# make necessary code changes
258# use git to commit changes
259repo upload --cbr -t .
260```
261
262The `--cbr` switch automatically picks the current repo branch for upload. The
AndroidX Core Team0db91f02021-05-06 22:45:18 +0000263`-t` switch sets the Gerrit topic to the branch name, e.g. `my-branch-name`. You
264can refer to the
265[Android documentation](https://source.android.com/setup/create/coding-tasks#workflow)
266for a high level overview of this basic workflow.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000267
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000268If you see the following prompt, choose `always`:
269
270```
271Run hook scripts from https://android.googlesource.com/platform/manifest (yes/always/NO)?
272```
273
274If the upload succeeds, you'll see an output like:
275
276```
277remote:
278remote: New Changes:
279remote: https://android-review.googlesource.com/c/platform/frameworks/support/+/720062 Further README updates
280remote:
281```
282
283To edit your change, use `git commit --amend`, and re-upload.
284
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000285NOTE If you encounter issues with `repo upload`, consider running upload with
286trace enabled, e.g. `GIT_DAPPER_TRACE=1 repo --trace upload . --cbr -y`. These
287logs can be helpful for reporting issues to the team that manages our git
288servers.
289
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000290NOTE If `repo upload` or any `git` command hangs and causes your CPU usage to
291skyrocket (e.g. your laptop fan sounds like a jet engine), then you may be
292hitting a rare issue with Git-on-Borg and HTTP/2. You can force `git` and `repo`
293to use HTTP/1.1 with `git config --global http.version HTTP/1.1`.
294
AndroidX Core Teamdeda2cf2021-08-06 15:14:40 -0700295### Fixing Kotlin code style errors
296
297`repo upload` automatically runs `ktlint`, which will cause the upload to fail
298if your code has style errors, which it reports on the command line like so:
299
300```
301[FAILED] ktlint_hook
302 [path]/MessageListAdapter.kt:36:69: Missing newline before ")"
303```
304
305To find and fix these errors, you can run ktlint locally, either in a console
306window or in the Terminal tool in Android Studio. Running in the Terminal tool
307is preferable because it will surface links to your source files/lines so you
308can easily navigate to the code to fix any problems.
309
310First, to run the tool and see all of the errors, run:
311
312`./gradlew module:submodule:ktlint`
313
314where module/submodule are the names used to refer to the module you want to
315check, such as `navigation:navigation-common`. You can also run ktlint on the
316entire project, but that takes longer as it is checking all active modules in
317your project.
318
319Many of the errors that ktlint finds can be automatically fixed by running
320ktlintFormat:
321
322`./gradlew module:submodule:ktlintFormat`
323
324ktlintFormat will report any remaining errors, but you can also run `ktlint`
325again at any time to see an updated list of the remaining errors.
326
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000327## Building {#building}
328
329### Modules and Maven artifacts {#modules-and-maven-artifacts}
330
331To build a specific module, use the module's `assemble` Gradle task. For
332example, if you are working on `core` module use:
333
334```shell
335./gradlew core:core:assemble
336```
337
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000338To make warnings fail your build (same as presubmit), use the `--strict` flag,
339which our gradlew expands into a few correctness-related flags including
340`-Pandroidx.allWarningsAsErrors`:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000341
342```shell
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000343./gradlew core:core:assemble --strict
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000344```
345
346To build every module, run the Lint verifier, verify the public API surface, and
347generate the local Maven repository artifact, use the `createArchive` Gradle
348task:
349
350```shell
351./gradlew createArchive
352```
353
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000354To run the complete build task that our build servers use, use the corresponding
355shell script:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000356
357```shell
AndroidX Core Team03b4da32021-03-10 23:20:41 +0000358./busytown/androidx.sh
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000359```
360
361### Attaching a debugger to the build
362
363Gradle tasks, including building a module, may be run or debugged from Android
364Studio's `Gradle` pane by finding the task to be debugged -- for example,
365`androidx > androidx > appcompat > appcompat > build > assemble` --
366right-clicking on it, and then selecting `Debug...`.
367
368Note that debugging will not be available until Gradle sync has completed.
369
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000370#### From the command line
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000371
372Tasks may also be debugged from the command line, which may be useful if
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000373`./studiow` cannot run due to a Gradle task configuration issue.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000374
3751. From the configurations dropdown in Studio, select "Edit Configurations".
3761. Click the plus in the top left to create a new "Remote" configuration. Give
377 it a name and hit "Ok".
3781. Set breakpoints.
3791. Run your task with added flags: `./gradlew <your_task_here>
380 -Dorg.gradle.debug=true --no-daemon`
3811. Hit the "Debug" button to the right of the configuration dropdown to attach
382 to the process.
383
384#### Troubleshooting the debugger
385
386If you get a "Connection refused" error, it's likely because a gradle daemon is
387still running on the port specified in the config, and you can fix this by
388killing the running gradle daemons:
389
390```shell
391./gradlew --stop
392```
393
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000394NOTE This is described in more detail in this
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000395[Medium article](https://medium.com/grandcentrix/how-to-debug-gradle-plugins-with-intellij-eef2ef681a7b).
396
397#### Attaching to an annotation processor
398
399Annotation processors run as part of the build, to debug them is similar to
400debugging the build.
401
402For a Java project:
403
404```shell
405./gradlew <your_project>:compileDebugJava --no-daemon --rerun-tasks -Dorg.gradle.debug=true
406```
407
408For a Kotlin project:
409
410```shell
411./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"
412```
413
414### Optional: Enabling internal menu in IntelliJ/Studio
415
416To enable tools such as `PSI tree` inside of IntelliJ/Studio to help debug
417Android Lint checks and Metalava, you can enable the
418[internal menu](https://www.jetbrains.org/intellij/sdk/docs/reference_guide/internal_actions/enabling_internal.html)
419which is typically used for plugin and IDE development.
420
421### Reference documentation {#docs}
422
423Our reference docs (Javadocs and KotlinDocs) are published to
424https://developer.android.com/reference/androidx/packages and may be built
425locally.
426
427NOTE `./gradlew tasks` always has the canonical task information! When in doubt,
428run `./gradlew tasks`
429
430#### Javadocs
431
432To build API reference docs for tip-of-tree Java source code, run the Gradle
433task:
434
435```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000436./gradlew doclavaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000437```
438
AndroidX Core Team8e522ba2021-09-14 07:07:45 -0700439Places the documentation in
440`{androidx-main}/out/androidx/docs-tip-of-tree/build/javadoc`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000441
442#### KotlinDocs
443
444To build API reference docs for tip-of-tree Kotlin source code, run the Gradle
445task:
446
447```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000448./gradlew dokkaKotlinDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000449```
450
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000451Places the documentation in
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000452`{androidx-main}/out/androidx/docs-tip-of-tree/build/dokkaKotlinDocs`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000453
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700454#### Dackka docs
455
456To build API reference docs for both Java and Kotlin source code using Dackka,
457run the Gradle task:
458
459```
460./gradlew dackkaDocs
461```
462
463Location of generated refdocs:
464
465* docs-public (what is published to DAC):
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000466 `{androidx-main}/out/androidx/docs-public/build/dackkaDocs`
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700467* docs-tip-of-tree:
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000468 `{androidx-main}/out/androidx/docs-tip-of-tree/build/dackkaDocs`
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700469
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000470#### Release docs
471
472To build API reference docs for published artifacts formatted for use on
473[d.android.com](http://d.android.com), run the Gradle command:
474
475```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000476./gradlew zipDoclavaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000477```
478
479This will create the artifact
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000480`{androidx-main}/out/dist/doclava-public-docs-0.zip`. This command builds docs
481based on the version specified in
AndroidX Core Team4e1909a2021-10-20 15:04:04 +0000482`{androidx-main-checkout}/frameworks/support/docs-public/build.gradle` and uses
483the prebuilt checked into
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000484`{androidx-main-checkout}/prebuilts/androidx/internal/androidx/`. We
AndroidX Core Team4e1909a2021-10-20 15:04:04 +0000485colloquially refer to this two step process of (1) updating `docs-public` and
486(2) checking in a prebuilt artifact into the prebuilts directory as
487[The Prebuilts Dance](releasing_detailed.md#the-prebuilts-dance™). So, to build
488javadocs that will be published to
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000489https://developer.android.com/reference/androidx/packages, both of these steps
490need to be completed.
491
492Once you done the above steps, Kotlin docs will also be generated, with the only
493difference being that we use the Gradle command:
494
495```
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000496./gradlew zipDokkaDocs
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000497```
498
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000499This will create the artifact `{androidx-main}/out/dist/dokka-public-docs-0.zip`
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000500
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700501To generate a zip artifact for both Java and Kotlin source code using Dackka:
502
503```
504./gradlew zipDackkaDocs
505```
506
507This will create the artifact
508`{androidx-main}/out/dist/dackka-public-docs-0.zip`
509
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000510### Updating public APIs {#updating-public-apis}
511
512Public API tasks -- including tracking, linting, and verifying compatibility --
513are run under the following conditions based on the `androidx` configuration
514block, evaluated in order:
515
516* `runApiTasks=Yes` => yes
517* `runApiTasks=No` => no
518* `toolingProject=true` => no
519* `mavenVersion` or group version not set => no
520* Has an existing `api/` directory => yes
521* `publish=SNAPSHOT_AND_RELEASE` => yes
522* Otherwise, no
523
524If you make changes to tracked public APIs, you will need to acknowledge the
525changes by updating the `<component>/api/current.txt` and associated API files.
526This is handled automatically by the `updateApi` Gradle task:
527
528```shell
529# Run updateApi for all modules.
530./gradlew updateApi
531
532# Run updateApi for a single module, ex. appcompat-resources in group appcompat.
533./gradlew :appcompat:appcompat-resources:updateApi
534```
535
536If you change the public APIs without updating the API file, your module will
537still build **but** your CL will fail Treehugger presubmit checks.
538
alanva5fd21b2021-08-20 10:26:46 -0700539#### What are all these files in `api/`? {#updating-public-apis-glossary}
540
541Historical API surfaces are tracked for compatibility and docs generation
542purposes. For each version -- including `current` to represent the tip-of-tree
543version -- we record three different types of API surfaces.
544
545* `<version>.txt`: Public API surface, tracked for compatibility
546* `restricted_<version>.txt`: `@RestrictTo` API surface, tracked for
547 compatibility where necessary (see
548 [Restricted APIs](api_guidelines.md#restricted-api))
549* `public_plus_experimental_<version>.txt`: Public API surface plus
550 `@RequiresOptIn` experimental API surfaces used for documentation (see
551 [Experimental APIs](api_guidelines.md#experimental-api)) and API review
552
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000553### Release notes & the `Relnote:` tag {#relnote}
554
555Prior to releasing, release notes are pre-populated using a script and placed
556into a Google Doc. The Google Doc is manually double checked by library owners
557before the release goes live. To auto-populate your release notes, you can use
558the semi-optional commit tag `Relnote:` in your commit, which will automatically
559include that message the commit in the pre-populated release notes.
560
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000561The presence of a `Relnote:` tag is required for API changes in `androidx-main`.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000562
563#### How to use it?
564
565One-line release note:
566
567``` {.good}
568Relnote: Fixed a critical bug
569```
570
571``` {.good}
572Relnote: "Fixed a critical bug"
573```
574
575``` {.good}
576Relnote: Added the following string function: `myFoo(\"bar\")`
577```
578
579Multi-line release note:
580
581Note: If the following lines do not contain an indent, you may hit b/165570183.
582
583``` {.good}
584Relnote: "We're launching this awesome new feature! It solves a whole list of
585 problems that require a lot of explaining! "
586```
587
588``` {.good}
589Relnote: """Added the following string function: `myFoo("bar")`
590 It will fix cases where you have to call `myFoo("baz").myBar("bar")`
591 """
592```
593
594Opt out of the Relnote tag:
595
596``` {.good}
597Relnote: N/A
598```
599
600``` {.good}
601Relnote: NA
602```
603
604NOT VALID:
605
606``` {.bad}
607Relnote: This is an INVALID multi-line release note. Our current scripts won't
608include anything beyond the first line. The script has no way of knowing when
609the release note actually stops.
610```
611
612``` {.bad}
613Relnote: This is an INVALID multi-line release note. "Quotes" need to be
614 escaped in order for them to be parsed properly.
615```
616
617### Common build errors
618
619#### Diagnosing build failures
620
621If you've encountered a build failure and you're not sure what is triggering it,
622then please run
623`./development/diagnose-build-failure/diagnose-build-failure.sh`.
624
625This script can categorize your build failure into one of the following
626categories:
627
628* The Gradle Daemon is saving state in memory and triggering a failure
629* Your source files have been changed and/or incompatible git commits have
630 been checked out
631* Some file in the out/ dir is triggering an error
632 * If this happens, diagnose-build-failure.sh should also identify which
633 file(s) specifically
634* The build is nondeterministic and/or affected by timestamps
635* The build via gradlew actually passes and this build failure is specific to
636 Android Studio
637
638Some more-specific build failures are listed below in this page.
639
640#### Out-of-date platform prebuilts
641
642Like a normal Android library developed in Android Studio, libraries within
643`androidx` are built against prebuilts of the platform SDK. These are checked in
644to the `prebuilts/fullsdk-darwin/platforms/<android-version>` directory.
645
646If you are developing against pre-release platform APIs in the internal
647`androidx-platform-dev` branch, you may need to update these prebuilts to obtain
648the latest API changes.
649
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000650#### Missing external dependency
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000651
652If Gradle cannot resolve a dependency listed in your `build.gradle`, you may
653need to import the corresponding artifact into `prebuilts/androidx/external`.
654Our workflow does not automatically download artifacts from the internet to
655facilitate reproducible builds even if remote artifacts are changed.
656
657You can download a dependency by running:
658
659```shell
660cd frameworks/support && ./development/importMaven/import_maven_artifacts.py -n 'someGroupId:someArtifactId:someVersion'
661```
662
663This will create a change within the `prebuilts/androidx/external` directory.
664Make sure to upload this change before or concurrently (ex. in the same Gerrit
665topic) with the dependent library code.
666
667Libraries typically reference dependencies using constants defined in
AndroidX Core Teama20829b2021-12-09 10:25:57 -0800668[`libs.versions.toml`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:gradle/libs.versions.toml),
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000669so please update this file to include a constant for the version of the library
670that you have checked in. You will reference this constant in your library's
671`build.gradle` dependencies.
672
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000673#### Dependency verification
674
675If the new dependency you are importing is unsigned, or is signed with a new,
676unrecognized key, then you will need to add new dependency verification metadata
677to indicate to Gradle that this new dependency is trusted. Instructions for how
678to do this are currently in the
679[README](https://android.googlesource.com/platform/frameworks/support/+/androidx-main/gradle/README.md)
680in the development subfolder
681
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000682#### Updating an existing dependency
683
684If an older version of a dependency prebuilt was already checked in, please
685manually remove it within the same CL that adds the new prebuilt. You will also
686need to update `Dependencies.kt` to reflect the version change.
687
688#### My gradle build fails with "Cannot invoke method getURLs() on null object"
689
690You're using Java 9's javac, possibly because you ran envsetup.sh from the
691platform build or specified Java 9 as the global default Java compiler. For the
692former, you can simply open a new shell and avoid running envsetup.sh. For the
693latter, we recommend you set Java 8 as the default compiler using sudo
694update-java-alternatives; however, if you must use Java 9 as the default then
695you may alternatively set JAVA_HOME to the location of the Java 8 SDK.
696
697#### My gradle build fails with "error: cannot find symbol" after making framework-dependent changes.
698
699You probably need to update the prebuilt SDK used by the gradle build. If you
700are referencing new framework APIs, you will need to wait for the framework
701changes to land in an SDK build (or build it yourself) and then land in both
702prebuilts/fullsdk and prebuilts/sdk. See
703[Updating SDK prebuilts](playbook.md#prebuilts-fullsdk) for more information.
704
705#### How do I handle refactoring a framework API referenced from a library?
706
707Because AndroidX must compile against both the current framework and the latest
708SDK prebuilt, and because compiling the SDK prebuilt depends on AndroidX, you
709will need to refactor in stages: Remove references to the target APIs from
710AndroidX Perform the refactoring in the framework Update the framework prebuilt
711SDK to incorporate changes in (2) Add references to the refactored APIs in
712AndroidX Update AndroidX prebuilts to incorporate changes in (4)
713
714## Testing {#testing}
715
716AndroidX libraries are expected to include unit or integration test coverage for
717100% of their public API surface. Additionally, all CLs must include a `Test:`
718stanza indicating which tests were used to verify correctness. Any CLs
719implementing bug fixes are expected to include new regression tests specific to
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000720the issue being fixed.
721
722### Running Tests
723
724#### Single Test Class or Method
725
7261. Open the desired test file in Android Studio.
7272. Right-click on a test class or @Test method name and select `Run FooBarTest`
728
729#### Full Test Package
730
7311. In the project side panel open the desired module.
7322. Find the directory with the tests
7333. Right-click on the directory and select `Run androidx.foobar`
734
735### Running Sample Apps
736
737The AndroidX repository has a set of Android applications that exercise AndroidX
738code. These applications can be useful when you want to debug a real running
739application, or reproduce a problem interactively, before writing test code.
740
741These applications are named either `<libraryname>-integration-tests-testapp`,
742or `support-\*-demos` (e.g. `support-v4-demos` or `support-leanback-demos`). You
743can run them by clicking `Run > Run ...` and choosing the desired application.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000744
745See the [Testing](testing.md) page for more resources on writing, running, and
746monitoring tests.
747
748### AVD Manager
749
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000750The Android Studio instance started by `./studiow` uses a custom SDK directory,
751which means any virtual devices created by a "standard" non-AndroidX instance of
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700752Android Studio will be *visible* from the `./studiow` instance but will be
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000753unable to locate the SDK artifacts -- they will display a `Download` button.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000754
755You can either use the `Download` button to download an extra copy of the SDK
AndroidX Core Teame1288a72021-09-03 12:30:13 -0700756artifacts *or* you can set up a symlink to your "standard" non-AndroidX SDK
AndroidX Core Teamee1457a2021-02-25 16:13:10 +0000757directory to expose your existing artifacts to the `./studiow` instance:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000758
759```shell
760# Using the default MacOS Android SDK directory...
761ln -s /Users/$(whoami)/Library/Android/sdk/system-images \
762 ../../prebuilts/fullsdk-darwin/system-images
763```
764
765### Benchmarking {#testing-benchmarking}
766
767Libraries are encouraged to write and monitor performance benchmarks. See the
AndroidX Core Team5a4c72f2022-01-12 09:34:38 -0800768[Benchmarking](benchmarking.md) and [Macrobenchmarking](macrobenchmarking.md)
769pages for more details, and the
770[Benchmarking section of d.android.com](http://d.android.com/benchmark) for more
771info on these tools.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000772
773## Library snapshots {#snapshots}
774
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000775### Quick how-to
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000776
777Add the following snippet to your build.gradle file, replacing `buildId` with a
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000778snapshot build ID.
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000779
780```groovy {highlight=context:[buildId]}
781allprojects {
782 repositories {
783 google()
784 jcenter()
785 maven { url 'https://androidx.dev/snapshots/builds/[buildId]/artifacts/repository' }
786 }
787}
788```
789
AndroidX Core Teamee9c1aa2021-04-06 17:29:05 +0000790You must define dependencies on artifacts using the `SNAPSHOT` version suffix,
791for example:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000792
793```groovy {highlight=context:SNAPSHOT}
794dependencies {
795 implementation "androidx.core:core:1.2.0-SNAPSHOT"
796}
797```
798
799### Where to find snapshots
800
801If you want to use unreleased `SNAPSHOT` versions of `androidx` artifacts, you
802can find them on either our public-facing build server:
803
804`https://ci.android.com/builds/submitted/<build_id>/androidx_snapshot/latest`
805
806or on our slightly-more-convenient [androidx.dev](https://androidx.dev) site:
807
808`https://androidx.dev/snapshots/builds/<build-id>/artifacts/repository` for a
809specific build ID
810
811`https://androidx.dev/snapshots/builds/latest/artifacts/repository` for
812tip-of-tree snapshots
813
814### Obtaining a build ID
815
816To browse build IDs, you can visit either
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000817[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?)
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000818on ci.android.com or [Snapshots](https://androidx.dev/snapshots/builds) on the
819androidx.dev site.
820
821Note that if you are using androidx.dev, you may substitute `latest` for a build
822ID to use the last known good build.
823
824To manually find the last known good `build-id`, you have several options.
825
826#### Snapshots on androidx.dev
827
828[Snapshots](https://androidx.dev/snapshots/builds) on androidx.dev only lists
829usable builds.
830
831#### Programmatically via `jq`
832
833Install `jq`:
834
835```shell
836sudo apt-get install jq
837```
838
839```shell
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000840ID=`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 +0000841 && echo https://ci.android.com/builds/submitted/"${ID:1:-1}"/androidx_snapshot/latest/raw/repository/
842```
843
844#### Android build server
845
846Go to
AndroidX Core Team408c27b2020-12-15 15:57:00 +0000847[androidx-main](https://ci.android.com/builds/branches/aosp-androidx-main/grid?)
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000848on ci.android.com.
849
850For `androidx-snapshot` target, wait for the green "last known good build"
851button to load and then click it to follow it to the build artifact URL.
852
853### Using in a Gradle build
854
855To make these artifacts visible to Gradle, you need to add it as a respository:
856
857```groovy
858allprojects {
859 repositories {
860 google()
861 maven {
862 // For all Jetpack libraries (including Compose)
863 url 'https://androidx.dev/snapshots/builds/<build-id>/artifacts/repository'
864 }
865 }
866}
867```
868
869Note that the above requires you to know the `build-id` of the snapshots you
870want.
871
872#### Specifying dependencies
873
874All artifacts in the snapshot repository are versioned as `x.y.z-SNAPSHOT`. So
875to use a snapshot artifact, the version in your `build.gradle` will need to be
876updated to `androidx.<groupId>:<artifactId>:X.Y.Z-SNAPSHOT`
877
878For example, to use the `core:core:1.2.0-SHAPSHOT` snapshot, you would add the
879following to your `build.gradle`:
880
881```
882dependencies {
883 ...
884 implementation("androidx.core:core:1.2.0-SNAPSHOT")
885 ...
886}
887```
888
889## FAQ {#faq}
890
891### How do I test my change in a separate Android Studio project? {#faq-test-change-studio}
892
893If you're working on a new feature or bug fix in AndroidX, you may want to test
894your changes against another project to verify that the change makes sense in a
895real-world context or that a bug's specific repro case has been fixed.
896
897If you need to be absolutely sure that your test will exactly emulate the
898developer's experience, you can repeatedly build the AndroidX archive and
899rebuild your application. In this case, you will need to create a local build of
900AndroidX's local Maven repository artifact and install it in your Android SDK
901path.
902
903First, use the `createArchive` Gradle task to generate the local Maven
904repository artifact:
905
906```shell
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000907# Creates <path-to-checkout>/out/androidx/build/support_repo/
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000908./gradlew createArchive
909```
910
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000911Using for your alternate (non-AndroidX) version of Android Studio open the
912project's 'build.gradle' and add the following within 'repositories' to make
913Android Gradle Plugin look for binaries in newly built repository:
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000914
915```groovy
916allprojects {
917 repositories {
918 ...
919 maven {
AndroidX Core Team21ccf652022-04-01 14:53:07 +0000920 url "<path-to-sdk>/out/androidx/build/support_repo/"
AndroidX Core Team2e416b22020-12-03 22:58:07 +0000921 }
922 }
923}
924```
925
926NOTE Gradle resolves dependencies in the order that the repositories are defined
927(if 2 repositories can resolve the same dependency, the first listed will do so
928and the second will not). Therefore, if the library you are testing has the same
929group, artifact, and version as one already published, you will want to list
930your custom maven repo first.
931
932Finally, in the dependencies section of your standalone project's `build.gradle`
933file, add or update the `implementation` entries to reflect the AndroidX modules
934that you would like to test. Example:
935
936```
937dependencies {
938 ...
939 implementation "androidx.appcompat:appcompat::1.0.0-alpha02"
940}
941```
942
943If you are testing your changes in the Android Platform code, you can replace
944the module you are testing
945`YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository` with your own
946module. We recommend only replacing the module you are modifying instead of the
947full m2repository to avoid version issues of other modules. You can either take
948the unzipped directory from
949`<path-to-checkout>/out/dist/top-of-tree-m2repository-##.zip`, or from
950`<path-to-checkout>/out/androidx/build/support_repo/` after buiding `androidx`.
951Here is an example of replacing the RecyclerView module:
952
953```shell
954$TARGET=YOUR_ANDROID_PATH/prebuilts/sdk/current/androidx/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07;
955rm -rf $TARGET;
956cp -a <path-to-sdk>/extras/m2repository/androidx/recyclerview/recyclerview/1.1.0-alpha07 $TARGET
957```
958
959Make sure the library versions are the same before and after replacement. Then
960you can build the Android platform code with the new `androidx` code.
AndroidX Core Team4cc85fa2021-11-23 15:58:34 +0000961
962### How do I measure library size? {#library-size}
963
964Method count and bytecode size are tracked in CI
965[alongside benchmarks](benchmarking.md#monitoring) to detect regressions.
966
967For local measurements, use the `:reportLibraryMetrics` task. For example:
968
969```shell
970./gradlew benchmark:benchmark-macro:reportLibraryMetrics
971cat ../../out/dist/librarymetrics/androidx.benchmark_benchmark-macro.json
972```
973
974Will output something like: `{"method_count":1256,"bytecode_size":178822}`
975
976Note: this only counts the weight of your library's jar/aar, including
977resources. It does not count library dependencies. It does not account for a
978minification step (e.g. with R8), as that is dynamic, and done at app build time
979(and depend on which entrypoints the app uses).