1*333d2b36SAndroid Build Coastguard Worker## Soong Android Resource Compilation 2*333d2b36SAndroid Build Coastguard Worker 3*333d2b36SAndroid Build Coastguard WorkerThe Android build process involves several steps to compile resources into a format that the Android app can use 4*333d2b36SAndroid Build Coastguard Workerefficiently in android_library, android_app and android_test modules. See the 5*333d2b36SAndroid Build Coastguard Worker[resources documentation](https://developer.android.com/guide/topics/resources/providing-resources) for general 6*333d2b36SAndroid Build Coastguard Workerinformation on resources (with a focus on building with Gradle). 7*333d2b36SAndroid Build Coastguard Worker 8*333d2b36SAndroid Build Coastguard WorkerFor all modules, AAPT2 compiles resources provided by directories listed in the resource_dirs directory (which is 9*333d2b36SAndroid Build Coastguard Workerimplicitly set to `["res"]` if unset, but can be overridden by setting the `resource_dirs` property). 10*333d2b36SAndroid Build Coastguard Worker 11*333d2b36SAndroid Build Coastguard Worker## android_library with resource processor 12*333d2b36SAndroid Build Coastguard WorkerFor an android_library with resource processor enabled (currently by setting `use_resource_processor: true`, but will be 13*333d2b36SAndroid Build Coastguard Workerenabled by default in the future): 14*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current 15*333d2b36SAndroid Build Coastguard Workerandroid_library module. `package-res.apk` files from transitive dependencies are passed to AAPT2 with the `-I` flag to 16*333d2b36SAndroid Build Coastguard Workerresolve references to resources from dependencies. 17*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an R.txt file that lists all the resources provided by the current android_library module. 18*333d2b36SAndroid Build Coastguard Worker- ResourceProcessorBusyBox reads the `R.txt` file for the current android_library and produces an `R.jar` with an 19*333d2b36SAndroid Build Coastguard Worker`R.class` in the package listed in the android_library's `AndroidManifest.xml` file that contains java fields for each 20*333d2b36SAndroid Build Coastguard Workerresource ID. The resource IDs are non-final, as the final IDs will not be known until the resource table of the final 21*333d2b36SAndroid Build Coastguard Workerandroid_app or android_test module is built. 22*333d2b36SAndroid Build Coastguard Worker- The android_library's java and/or kotlin code is compiled with the generated `R.jar` in the classpath, along with the 23*333d2b36SAndroid Build Coastguard Worker`R.jar` files from all transitive android_library dependencies. 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker## android_app or android_test with resource processor 26*333d2b36SAndroid Build Coastguard WorkerFor an android_app or android_test with resource processor enabled (currently by setting `use_resource_processor: true`, 27*333d2b36SAndroid Build Coastguard Workerbut will be enabled by default in the future): 28*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current 29*333d2b36SAndroid Build Coastguard Workerandroid_app or android_test, as well as all transitive android_library modules referenced via `static_libs`. The 30*333d2b36SAndroid Build Coastguard Workercurrent module is overlaid on dependencies so that resources from the current module replace resources from dependencies 31*333d2b36SAndroid Build Coastguard Workerin the case of conflicts. 32*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an R.txt file that lists all the resources provided by the current android_app or android_test, as 33*333d2b36SAndroid Build Coastguard Workerwell as all transitive android_library modules referenced via `static_libs`. The R.txt file contains the final resource 34*333d2b36SAndroid Build Coastguard WorkerID for each resource. 35*333d2b36SAndroid Build Coastguard Worker- ResourceProcessorBusyBox reads the `R.txt` file for the current android_app or android_test, as well as all transitive 36*333d2b36SAndroid Build Coastguard Workerandroid_library modules referenced via `static_libs`, and produces an `R.jar` with an `R.class` in the package listed in 37*333d2b36SAndroid Build Coastguard Workerthe android_app or android_test's `AndroidManifest.xml` file that contains java fields for all local or transitive 38*333d2b36SAndroid Build Coastguard Workerresource IDs. In addition, it creates an `R.class` in the package listed in each android_library dependency's 39*333d2b36SAndroid Build Coastguard Worker`AndroidManifest.xml` file that contains final resource IDs for the resources that were found in that library. 40*333d2b36SAndroid Build Coastguard Worker- The android_app or android_test's java and/or kotlin code is compiled with the current module's `R.jar` in the 41*333d2b36SAndroid Build Coastguard Workerclasspath, but not the `R.jar` files from transitive android_library dependencies. The `R.jar` file is also merged into 42*333d2b36SAndroid Build Coastguard Workerthe program classes that are dexed and placed in the final APK. 43*333d2b36SAndroid Build Coastguard Worker 44*333d2b36SAndroid Build Coastguard Worker## android_app, android_test or android_library without resource processor 45*333d2b36SAndroid Build Coastguard WorkerFor an android_app, android_test or android_library without resource processor enabled (current the default, or 46*333d2b36SAndroid Build Coastguard Workerexplicitly set with `use_resource_processor: false`): 47*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current 48*333d2b36SAndroid Build Coastguard Workerandroid_app, android_test or android_library module, as well as all transitive android_library modules referenced via 49*333d2b36SAndroid Build Coastguard Worker`static_libs`. The current module is overlaid on dependencies so that resources from the current module replace 50*333d2b36SAndroid Build Coastguard Workerresources from dependencies in the case of conflicts. 51*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an `R.java` file in the package listed in each the current module's `AndroidManifest.xml` file that 52*333d2b36SAndroid Build Coastguard Workercontains resource IDs for all resources from the current module as well as all transitive android_library modules 53*333d2b36SAndroid Build Coastguard Workerreferenced via `static_libs`. The same `R.java` containing all local and transitive resources is also duplicated into 54*333d2b36SAndroid Build Coastguard Workerevery package listed in an `AndroidManifest.xml` file in any static `android_library` dependency. 55*333d2b36SAndroid Build Coastguard Worker- The module's java and/or kotlin code is compiled along with all the generated `R.java` files. 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker 58*333d2b36SAndroid Build Coastguard Worker## Downsides of legacy resource compilation without resource processor 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard WorkerCompiling resources without using the resource processor results in a generated R.java source file for every transitive 61*333d2b36SAndroid Build Coastguard Workerpackage that contains every transitive resource. For modules with large transitive dependency trees this can be tens of 62*333d2b36SAndroid Build Coastguard Workerthousands of resource IDs duplicated in tens to a hundred java sources. These java sources all have to be compiled in 63*333d2b36SAndroid Build Coastguard Workerevery successive module in the dependency tree, and then the final R8 step has to drop hundreds of thousands of 64*333d2b36SAndroid Build Coastguard Workerunreferenced fields. This results in significant build time and disk usage increases over building with resource 65*333d2b36SAndroid Build Coastguard Workerprocessor. 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker## Converting to compilation with resource processor 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker### Reference resources using the package name of the module that includes them. 70*333d2b36SAndroid Build Coastguard WorkerConverting an android_library module to build with resource processor requires fixing any references to resources 71*333d2b36SAndroid Build Coastguard Workerprovided by android_library dependencies to reference the R classes using the package name found in the 72*333d2b36SAndroid Build Coastguard Worker`AndroidManifest.xml` file of the dependency. For example, when referencing an androidx resource: 73*333d2b36SAndroid Build Coastguard Worker```java 74*333d2b36SAndroid Build Coastguard WorkerView.inflate(mContext, R.layout.preference, null)); 75*333d2b36SAndroid Build Coastguard Worker``` 76*333d2b36SAndroid Build Coastguard Workermust be replaced with: 77*333d2b36SAndroid Build Coastguard Worker```java 78*333d2b36SAndroid Build Coastguard WorkerView.inflate(mContext, androidx.preference.R.layout.preference, null)); 79*333d2b36SAndroid Build Coastguard Worker``` 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Worker### Use unique package names for each module in `AndroidManifest.xml` 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard WorkerEach module will produce an `R.jar` containing an `R.class` in the package specified in it's `AndroidManifest.xml`. 84*333d2b36SAndroid Build Coastguard WorkerIf multiple modules use the same package name they will produce conflicting `R.class` files, which can cause some 85*333d2b36SAndroid Build Coastguard Workerresource IDs to appear to be missing. 86*333d2b36SAndroid Build Coastguard Worker 87*333d2b36SAndroid Build Coastguard WorkerIf existing code has multiple modules that contribute resources to the same package, one option is to move all the 88*333d2b36SAndroid Build Coastguard Workerresources into a single resources-only `android_library` module with no code, and then depend on that from all the other 89*333d2b36SAndroid Build Coastguard Workermodules.