androidandroid-studioaarr.java-fileaapt

What the purpose of the R.txt file inside aar?


Sometime I can see a R.txt file in some .aar (and in such case there is also a non-empty ./res directory in the aar). What the exact purpose of this R.txt file? Also sometime I can see some AAR with a non-empty ./res directory but without any R.txt, is it normal ?


Solution

  • The short answer

    A R.txt file in a foo.aar file serves

    The purpose of R.txt is basically the same as of R.java -- mapping resources to IDs --, therefore you'll find a R.txt in an .aar file with a non-empty /res folder. In case of an empty /res folder there's either no R.txt at all, or an empty R.txt of size zero.

    The TL;DR addendum

    As described in the Chromium Googlesource article on the Life of an Android Resource, R.txt is an intermediate file on the way to an APK, containing a list of resources and their IDs. It is also archived to help with debugging, as a simple .txt file is easier to parse than the final .java file.

    Actually it's not that intermediate, as it is also characterized as a final file that is put into the out/*/apks directory next to the final .apk file. Now, in case of an library .aar file it is put directly into the output (.aar) file together with other debugging and configuration files like lint.jar.

    In an .aar file, which can be used as a dependency for other libraries as well as for APKs, R.txt has an additional role. Except for being used for debugging it also serves as an input for the next level file build in the dependency hierarchy.

    Lets take a look on the entries in R.txt. Their structure is as follows (read "res" as "resource"). A line ends with a newline.

    <type> <res_class> <res_name> <res_id>
    

    This information matches the information in R.java like this:

    public static final class <res_class> {
            public static final <type> <res_name> = <res_id>;
            //...
    }
    

    The above mentioned article shows a sample R.java from package org.chromium.ui.

    public final class R {
        public static final class attr {
            public static final int buttonAlignment = 0x7f030038;
            public static final int buttonColor = 0x7f03003e;
            public static final int layout = 0x7f030094;
            public static final int roundedfillColor = 0x7f0300bf;
            public static final int secondaryButtonText = 0x7f0300c4;
            public static final int stackedMargin = 0x7f0300d4;
        }
        public static final class id {
            public static final int apart = 0x7f080021;
            public static final int dropdown_body_footer_divider = 0x7f08003d;
            public static final int dropdown_body_list = 0x7f08003e;
            public static final int dropdown_footer = 0x7f08003f;
        }
        public static final class layout {
            public static final int dropdown_item = 0x7f0a0022;
            public static final int dropdown_window = 0x7f0a0023;
        }
    }
    

    The corresponding R.txt will therefore be:

    int attr buttonAlignment 0x7f030038
    int attr buttonColor 0x7f03003e
    int attr layout 0x7f030094
    int attr roundedfillColor 0x7f0300bf
    int attr secondaryButtonText 0x7f0300c4
    int attr stackedMargin 0x7f0300d4
    int id apart 0x7f080021
    int id dropdown_body_footer_divider 0x7f08003d
    int id dropdown_body_list 0x7f08003e
    int id dropdown_footer 0x7f08003f
    int layout dropdown_item 0x7f0a0022
    int layout dropdown_window 0x7f0a0023
    

    Now, in an APK building without AARs, the resource IDs from R.txt will be taken over as-is to R.java. However, this won't work with AARs because of the variable structure of resource ID's.

    So, this way you can have the same ID, lets say 0x7f030038, in several R.txt files from your dependency AARs, which will describe completely different resources. Therefore, while building an APK (or another higher-level AAR), all the R.txt files from dependencies will be put together with the APK's own temporary R.txt file and a new, final, R.txt will be written, with unique IDs for the APK's resources.