当前位置:   article > 正文

Android构建流程——篇四_build/generated/res/pngs

build/generated/res/pngs

Task9 generateDebugResValues

1. input/ouput

taskName:generateDebugResValues
=========================================================
output:/Users/dingbaosheng/work/mockuai/project/AndroidGradleTaskDemo/app/build/generated/res/resValues/debug
  • 1
  • 2
  • 3

简单的说该任务就是生成一个generated.xml文件,里面包含了在build.gradle文件中自定义的资源属性

  1. 配置自定义资源属性
    在这里插入图片描述
  2. 输出xml文件结构
    在这里插入图片描述

2. 核心类(GenerateResValues)

public class GenerateResValues extends AndroidBuilderTask {
   
	@TaskAction
    void generate() throws IOException, ParserConfigurationException {
   
        File folder = getResOutputDir();
		
		//1. 读取build.gradle中自定义的资源配置数据项
        List<Object> resolvedItems = getItems();
		
		//2. 如果未自定义,清空旧数据
        if (resolvedItems.isEmpty()) {
   
            FileUtils.cleanOutputDir(folder);
        } else {
   
        	//如果自定义了,将自定义资源数据项交给资源值生成器对象
            ResValueGenerator generator = new ResValueGenerator(folder);
            generator.addItems(getItems());
			
			//3. 生成generated.xml
            generator.generate();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

代码看流程清晰明了,关键代码就是将自定义属性(支持12种类型属性哦)写入到xml文件中,其实现细节集中在类ResValueGenerator.generater中;内部主要使用DOM API来实现,具体不再详细说明,贴下实现代码

public class ResValueGenerator {
   

    public static final String RES_VALUE_FILENAME_XML = "generated.xml";

    private static final List<ResourceType> RESOURCES_WITH_TAGS = ImmutableList.of(
            ResourceType.ARRAY,
            ResourceType.ATTR,
            ResourceType.BOOL,
            ResourceType.COLOR,
            ResourceType.DECLARE_STYLEABLE,
            ResourceType.DIMEN,
            ResourceType.FRACTION,
            ResourceType.INTEGER,
            ResourceType.PLURALS,
            ResourceType.STRING,
            ResourceType.STYLE);
	/**
     * Generates the resource files
     */
    public void generate() throws IOException, ParserConfigurationException {
   
        File pkgFolder = getFolderPath();
        if (!pkgFolder.isDirectory()) {
   
            if (!pkgFolder.mkdirs()) {
   
                throw new RuntimeException("Failed to create " + pkgFolder.getAbsolutePath());
            }
        }

        File resFile = new File(pkgFolder, RES_VALUE_FILENAME_XML);

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(false);
        factory.setIgnoringComments(true);
        DocumentBuilder builder;

        builder = factory.newDocumentBuilder();
        Document document = builder.newDocument();
		
		//创建根节点resources
        Node rootNode = document.createElement(TAG_RESOURCES);
        document.appendChild(rootNode);
		
		//添加子节点,此处就是添加些注释说明
        rootNode.appendChild(document.createTextNode("\n"));
        rootNode.appendChild(document.createComment("Automatically generated file. DO NOT MODIFY"));
        rootNode.appendChild(document.createTextNode("\n\n"));
		
		//遍历自定义资源属性
        for (Object item : mItems) {
   
            if (item instanceof ClassField) {
   
                ClassField field = (ClassField)item;

                ResourceType type = ResourceType.getEnum(field.getType());
				
				//判断是否是通用的11种类型中一种
                boolean hasResourceTag = (type != null && RESOURCES_WITH_TAGS.contains(type));
				
				//如果不是通用的资源类型,则生成<item>标签节点
                Node itemNode = document.createElement(hasResourceTag ? field.getType() : TAG_ITEM);
                Attr nameAttr = document.createAttribute(ATTR_NAME);

                nameAttr.setValue(field.getName());
                itemNode.getAttributes().setNamedItem(nameAttr);
				
				
                if (!hasResourceTag) {
   
                	//如果是item标签,需要设置其type、name属性值
                	//eg:<item type="id" name="button_ok" />
                    Attr typeAttr = document.createAttribute(ATTR_TYPE);
                    typeAttr.setValue(field.getType());
                    itemNode.getAttributes().setNamedItem(typeAttr);
                }

                if (type == ResourceType.STRING) {
   
                	//如果是string资源,添加traslatable属性,使其设备统一使用该字段,和系统语言等无关
                    Attr translatable = document.createAttribute(ATTR_TRANSLATABLE);
                    translatable.setValue(VALUE_FALSE);
                    itemNode.getAttributes().setNamedItem(translatable);
                }

                if (!field.getValue().isEmpty()) {
   
                    itemNode.appendChild(document.createTextNode(field.getValue()));
                }

                rootNode.appendChild(itemNode);
            } else if (item instanceof String) {
   
                rootNode.appendChild(document.createTextNode("\n"));
                rootNode.appendChild(document.createComment((String) item));
                rootNode.appendChild(document.createTextNode("\n"));
            }
        }

        String content;
        try {
   
            content = XmlPrettyPrinter.prettyPrint(document, true);
        } catch (Throwable t) {
   
            content = XmlUtils.toXml(document);
        }
		
		//写文件
        Files.write(content, resFile, Charsets.UTF_8);
    }
}    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

支持的自定义资源属性类型

序号 类型
1 array
2 attr
3 bool
4 color
5 declare-styleable
6 dimen
7 fraction
8 integer
9 plurals
10 string
11 style
12 item

Task10 generateDebugResources

属于空task直接忽略

Task11 mergeDebugResources

合并资源任务

1. input/ouput

taskName:mergeDebugResources
input:/Users/apple/.gradle/caches/transforms-1/files-1.1/aapt2-3.2.0-4818971-osx.jar/c5355294e416159d9559f45d46460f7d/aapt2-3.2.0-4818971-osx
input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/res/resValues/debug
input:/Users/apple/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/2774ea4f1cf1e83a6ad8e8d3c8b463b6/res
input:/Users/apple/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.1.3.aar/f43c0ba95b6494825ed940fc4f04662b/res
input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-media-compat-26.1.0.aar/53ab5ad72634f3497309a8788f3ca200/res
input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-compat-26.1.0.aar/4ec3c1c46e5bad9ac3b91f45a2afec3e/res
input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/res/rs/debug
input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/main/res
input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/debug/res
=========================================================
output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/blame/res/debug
output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/res/pngs/debug
output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/incremental/mergeDebugResources
output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/res/merged/debug
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

先来一张总流程图吧,先把握主线;文字描述的不一定有图清楚
在这里插入图片描述

xml -> drawable 、string 、color、anim、layout、value
layout、generated
png
先看输入好了,可以很清楚看到输入都是项目依赖的库的res文件以及本身结构的res文件

输出路径 产物 备注 所在类
app/build/intermediates/blame/res/debug 1. 日志文件 2. 资源文件和编译后产物的映射表文件
app/build/generated/res/pngs/debug 资源文件vector、png xxx
app/build/intermediates/incremental/mergeDebugResources 1、merged.dir 存放合并资源文件的地方2、stripped.dir 3、compile-file-map.properties 资源和编译产物映射表 4、merger.xml 合并文件 MergedResourceWriter
app/build/intermediates/res/merged/debug flat文件 AAPT2编译的产物,也就是本上图的重点产物 MergedResourceWriter

app/build/intermediates/incremental/mergeDebugResources

  1. merged.dir
  2. stripped.dir
  3. compile-file-map.properties
  4. merger.xml

2. 核心类(MergeResources)

@CacheableTask
public class MergeResources extends IncrementalTask {
   
	
	@Override
    protected void doFullTaskAction() throws IOException, JAXBException {
   
        ResourcePreprocessor preprocessor = getPreprocessor();

        // this is full run, clean the previous outputs
        File destinationDir = getOutputDir();
        FileUtils.cleanOutputDir(destinationDir);
        if (dataBindingLayoutInfoOutFolder != null) {
   
            FileUtils.deleteDirectoryContents(dataBindingLayoutInfoOutFolder);
        }

        List<ResourceSet> resourceSets = getConfiguredResourceSets(preprocessor);

        // create a new merger and populate it with the sets.
        ResourceMerger merger = new ResourceMerger(minSdk.get());
        MergingLog mergingLog = null;
        if (blameLogFolder != null) {
   
            FileUtils.cleanOutputDir(blameLogFolder);
            mergingLog = new MergingLog(blameLogFolder);
        }

        try (ResourceCompilationService resourceCompiler =
                getResourceProcessor(
                        aaptGeneration,
                        getBuilder(),
                        aapt2FromMaven,
                        workerExecutorFacade,
                        crunchPng,
                        variantScope,
                        mergingLog,
                        flags,
                        processResources)) {
   

            for (ResourceSet resourceSet : resourceSets) {
   
                resourceSet.loadFromFiles(getILogger());
				//1. 添加资源
                merger.addDataSet(resourceSet);
            }

            MergedResourceWriter writer =
                    new MergedResourceWriter(
                            workerExecutorFacade,
                            destinationDir,
                            getPublicFile(),
                            mergingLog,
                            preprocessor,
                            resourceCompiler,
                            getIncrementalFolder(),
                            dataBindingLayoutProcessor,
                            mergedNotCompiledResourcesOutputDirectory,
                            pseudoLocalesEnabled,
                            getCrunchPng());
			//2. 执行资源合并操作
            merger.mergeData
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/275414
推荐阅读
相关标签
  

闽ICP备14008679号