This article has participated in the good article call order activity, click to see: [back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!]

preface

In work and study, we should not only write some business code, but also have a certain understanding of the compilation and packaging process of the project, so that we can have a clue when we encounter related problems. In the process, we tend to ignore how the resource files are added, the Android resource management framework is a very large and complex framework, resource compiler packaging process is very complex and complicated, this paper is to discuss about the Android resource file is how to compile and package, except as a self summary, Also hope to see this article you have help and inspiration. Of course, the article is long, I hope you can read it patiently.

Compile and Package process

In addition to code, there are many resource files in an Android package. These resource files are packaged into APK through the AAPT tool during apK packaging. Let’s first look at the apK packaging flowchart,

To summarize this diagram, there are several main steps in packaging:

  • Package resource files: use aapt to package files in the res directory to generate r.java files and resources.arsc resource files, such as Androidmanifest.xml and XML layout files.
  • Handle AIDL Files: If you have an AIDL interface, package it as a Java interface class using the AIDL tool
  • Java Compiler: A javAC Compiler that compiles R.java, source files, and aidl. Java into class files
  • Dex: source code. Class. Class files such as third-party JAR packages are generated using the DX tool
  • Apkbuilder: ApkBuilder packages all the compiled and uncompiled resources, dex files, arSC resource files into a complete APK file
  • Jarsigner: The above generated is an APK file without a signature. Here, the tool jarsigner is used to sign the APK to get an APK file with a signature
  • Zipalign: Alignments all resource files in the APK package to an integer multiple of 4 from the start of the file, thus reducing memory overhead at runtime

The resource classification

The asset catalog

The system does not compile resource files in this directory. Therefore, you cannot access these files by id. If you want to access these files, you need to specify the file name. Raw files can be accessed via AssetManager, which allows you to open and read raw resource files bound to your application in the form of a simple byte stream. Here is an instance of reading a local JSON file from assets:

StringBuilder sb = new StringBuilder(); AssetManager assets = getAssets(); Try {InputStream open = assets.open(" xxx.json "); InputStreamReader InputStreamReader = new InputStreamReader(open); // BufferedReader = New BufferedReader(inputStreamReader); String readLine; while((readLine = reader.readLine())! =null){ sb.append(readLine); } String s = sb.toString(); } catch (IOException e) { e.printStackTrace(); }Copy the code

What do you put in the asset directory of a typical project

Res directory

It stores compilable resource files (except raw). During compilation, the system automatically generates the id of the resource file in the R.java file. You can access the resource by r.xx.id.

directory The resource type
animator/ XML used to define attribute animation
anim/ XML to define tween animation (attribute animation can also be defined here)
color/ XML for the color state list
drawable/ Bitmap files (.9.png,.png,.jpg,.gif)
mipmap/ Drawable object file for different densities of initiator ICONS
layout/ An XML file that defines the layout of the user interface
menu/ An XML file that defines an application menu, such as an options menu, context menu, or submenu
values/ An XML file containing simple values such as strings, integers, and colors
XML/ Any XML file that can be read at run time by calling resources.getxml (). Various XML configuration files, such as searchable configurations, must be saved here.
font/ Font files with extensions (such as.ttf,.otf, or.ttc), or XML files that contain elements
raw/ Any file that needs to be saved in its original form

The result of compiling the resource file

benefit

There are two benefits to compiling resources

  • Small space: Binary XML files take up less space because all the strings involved in the tags, attribute names, attribute values, and content of all XML files are uniformly collected into a string pool. With this string pool, you can use an integer index instead of a string, thus reducing the size of the file
  • Fast parsing: The binary XML file parses faster, and since the XML file does not contain string values, it saves time parsing strings, thus increasing speed.

When compiled, all the resources except assets are given an ID. Based on these ids, the packaging tool generates a resource index table resources.arsc and an R.java file. The resource index table records the information of all resources and quickly matches the most appropriate resources according to the resource ID and device information. The R file records the ID constants of each resource.

Generate a resource index table

First, let’s take a look at the structure of resources.arSC

The entire resources.arsc consists of a series of chunks. Each chunk has a header that describes the metadata of the chunk.

  • Header: The header of each chunk describes the meta information of the chunk, including the type, header size, and block size of the current chunk
  • Global String Pool: All strings are put into this Pool. Everyone reuse the data from this Pool. What kind of strings are put into this Pool? The file path name of all the resources, and the value of the resources defined in the resource file, so the pool can also be calledResource item value strings A resource pool that contains the value strings of all resource items defined in the resource bundle, as shown in the following codeABCIt’s stored here
  • Package data block:
    • Package header: Records the metadata of the package, including the name, size, and type of the package
    • Resource type string pool: Stores all types of strings, such as attr, Drawable, Layout, and ANim
    • Resource item name String pool: Stores strings related to resource item names in all resource files of the application, such as the followingapp_nameIt’s stored here.
    • Type Spec: Indicates the Type specification data block, which describes the configuration difference of each resource item. Through the description of the configuration difference, we can know the configuration status of each resource item. Many Android devices, in order to make the application support for different size, density, language, Android will resource organization for 18 dimensions, each resource class corresponding to a set of configuration list, configure the resources of different dimensions, and then use a set of matching algorithm for application in the resources directory to select the most appropriate resources.
    • Config List: As mentioned above, each type spec is a description of a type, and each type can have multiple dimensions. Config List is described by multiple ResTable_type structures, each ResTable_type describing one dimension.
 <resources>    
      <string name="app_name">ABC</string>    
  </resources>
Copy the code

Generate R files and resource ids

First look at the R file structure. Each resource file corresponds to a static inner class. Compared to the directory structure of the RES file mentioned earlier, each static inner class defines a resource identifier

Or this:

    public static final class layout {
        public static final int main=0x7f030000;
    }
Copy the code

public static final int main=0x7f030000; Represents the main.xml file in the Layout directory. The highest byte in the ID represents the ID of package, the next highest byte represents the ID of type, and the last byte represents the sequence number that appears in the current type.

  • Package ID: is equivalent to a namespace that defines the source of resources. Android currently defines two resource command Spaces, of which the system resource command space is0x01, the other application resource command space is0x7f, all packageids between 0x01 and 0x7f are valid.
  • Type ID: Indicates the type ID of the resource. For example, ANIM, Color, Layout, RAW… Each resource corresponds to a type ID
  • Entry ID: Indicates the order in which each resource appears in the resource type to which it belongs. Entry IDS of different resource types may be the same, but their type ids are different, so they can be distinguished.

Resource files can only begin with a lowercase letter or underscore, followed by names with a-z or 0-9 or _. These characters, otherwise an error will be reported.

When we add a resource file to the corresponding res resource directory, a static constant is automatically generated in the static inner class of the corresponding R file to index the added file.

When we need to add an ID attribute to the component in the layout file, we can use @+ ID /idname, where + means to add a record in the inner class named ID in the R file. If this ID does not exist, it is generated first.

Resource file packaging process

Now that you have some basic information about resource files in the APK package, let’s talk about how resource files are packaged into apK. This process is very complicated and needs to be understood and memorized.

Before compiling an application resource, the Android resource packaging tool creates a ResourceTable, ResourceTable. When the application resource is compiled, this ResourceTable contains all the information about the resource. The resource index file resources.arsc can be generated from this ResourceTable.

Parsing AndroidManifest. XML

Get the package name, minSdkVersion, and so on of the application for which the resource is to be compiled. With the package name, you can create the ResourceTable, which is called ResourceTable.

Adds the referenced resource bundle

Usually when compiling an APK package, there are at least two resource bundles involved. One is the referenced system resource bundle, which contains many system level resources. For example, we know the four layouts LinearLayout, FrameLayout, and so on, along with the properties layout_width, layout_height, layout_oritation, and so on. Another is the resource bundle for the application that is currently being compiled.

Collecting resource files

Before compiling the application resources, Aapt creates the AaptAssets object to collect the current resource files that need to be compiled. These resource files are stored in the MEMBER variable mRes of AaptAssets class.

Add the collected resources to the ResourceTable ResourceTable

After adding resources to AaptAssets, this step adds resources to ResourceTable. Finally, we need to generate resources.arsc resource index table based on this ResourceTable. Looking back at the structure diagram of arsc file, it also has a ResourceTable.

The resources collected from the resource table in this step do not include values, because values must be compiled before being added to the resource table

Compile the Values resource

The VALUES resource is a description of some simple lightweight resources, such as Strings/Colors/Dimen, that are collected during compilation

Assign an ID to the resource bag

Under values, in addition to strings, there are some special resources that define their own values, such as the Orientation attribute of LinearLayout, which is vertical and horizontal, This is equivalent to defining the vertical and Horizontal bags.

Before compiling any other non-VALUES resources, we need to assign a resource ID to the PREVIOUSLY collected BAG resource because it may be referenced by other non-VALUES resources.

Compiling an XML file

The previous six steps have set the stage for compiling the XML file, gathered all the resources needed for XML, and now you can start compiling XML files such as layout, anims, animators, and so on. Compiling XML files can be divided into four steps

Parsing XML files

This step converts the XML file into a series of tree-shaped XMLNodes, each of which represents an XML element. After parsing, a root node XMLNode is obtained, from which the following operations can be performed

Attribute name ID

This step assigns a resource ID to the attribute name of each XML element, such as a TextView control that has attributes layout_width and layout_height. In the case of a system resource bundle, these attribute names are defined as a list of bag resources that are assigned resource ids at compile time.

For each XML file, the resource ID is assigned to the attribute name from the root node, and then the resource ID is assigned to each child node attribute name recursively until the resource ID is assigned to the attribute name of each node.

Parse attribute value

This step is a step up from the previous step, where we assigned an ID to each attribute, and this step parses the corresponding value of the attribute, for example, for the TextView we just just parses the width and height values, which could be match_parent or it could be warp_Content.

Flatten the XML file

To flatten an XML file into a binary format, there are several steps

  1. Collect attribute name strings with resource ids and put them in an array. These collected attribute name strings are stored in the string resource pool and correspond one-to-one to the collected array of resource ids.
  2. Collect all other strings in the XML file, that is, strings without resource ids
  3. By writing an XML header, the resulting XML binary is a series of chunks, each of which has a header that describes the meta information.
  4. Write the resource pool String to the Global String pool, which is the Global String resource pool in the arSC file structure
  5. Write the resource ID, collect all the resource IDS, which are used when generating the package, corresponding to the structure of the ARSC file package.
  6. To flattens an XML file is to replace the strings in each XML element, either with an index to the string resource pool or with another value of type

Generates a resource symbol for a resource

The resource symbol is generated here to prepare for the generation of R files later. The previous operation saves all the collected resource files in the ResourceTable by type, which is called the ResourceTable object. Aapt only needs to traverse the type in each package, then take out the name of each entry, calculate the corresponding resource ID according to the order in which it appears in the corresponding type, and then get the resource symbol. Resource symbol = Name + resource ID

Generate a resource index table based on the resource ID

Here we will generate resources.arsc, breaking down the steps of its generation again

  1. Collect type strings according to package, such as Drawable, String, Layout, ID, etc. The current compiled application has several packages, corresponding to several groups of type strings, each group of type strings stored in its own package.
  2. Collect resource name strings, again in package, as in string.xml,<resources>    <string name="app_name">ABC</string>  </resources>The app_name attribute can be collected
  3. Collect the resource item value string, using the string.xml above to collect ABC
  4. To generate package data blocks, step by step parse and collect the package format in the resources.arsc file format described above
  5. Writes the resource index table header, which is ResTable_header
  6. In step 3 above, all the value strings are collected. Here, just write them directly
  7. Write the Package data block. Write the Package data block collected in step 4 to the resource index table.

After these steps, the resource item index table resources.arsc is generated.

Compile the Androidmanifest.xml file

After the above steps, all the resources of the application are compiled. Here, the application configuration file androidmanifest.xml is also compiled into a binary file.

Generate R files

At this point, we know all the resources and their corresponding ids, and we can happily write to the R file, in different static inner classes depending on the type, just like the format of the R file described earlier.

Packaging to the APK

Once all the resource files have been compiled and generated, they can be packaged into apK

  • Assets directory
  • Res directory, except values, because the resource files in values directory have been compiled and directly written to the resource index table
  • Resource index table resources.arsc
  • Files other than resource files (dex, Androidmanifest.xml, signature information, etc.)

conclusion

Finally, the compilation and packaging process of the entire resource file is really a very complicated and tedious process. In the process of reading, we should always compare those several organization diagrams to have a better understanding of these files. Resource files are very important in learning and working on Android. Many times these knowledge will be ignored, but if you have time to have a good grasp of these knowledge will be a great improvement for yourself.

Draw a flow chart

Finally, a flowchart is used to review the entire process

The resources

  • Blog.csdn.net/Luoshengyan…
  • Blog.csdn.net/luoshengyan…
  • www.cnblogs.com/feng9exe/p/…
  • Blog.csdn.net/jieqiang3/a…
  • Blog.csdn.net/weixin_3394…