赞
踩
taskName:generateDebugResValues
=========================================================
output:/Users/dingbaosheng/work/mockuai/project/AndroidGradleTaskDemo/app/build/generated/res/resValues/debug
简单的说该任务就是生成一个generated.xml文件,里面包含了在build.gradle文件中自定义的资源属性
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(); } } }
代码看流程清晰明了,关键代码就是将自定义属性(支持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 | array |
2 | attr |
3 | bool |
4 | color |
5 | declare-styleable |
6 | dimen |
7 | fraction |
8 | integer |
9 | plurals |
10 | string |
11 | style |
12 | item |
属于空task直接忽略
合并资源任务
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
先来一张总流程图吧,先把握主线;文字描述的不一定有图清楚
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
@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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。