
com.android.build.gradle.tasks.PreprocessResourcesTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-core Show documentation
Show all versions of gradle-core Show documentation
Amazon Core library to build Android Gradle plugin.
The newest version!
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.build.gradle.tasks;
import com.android.build.gradle.internal.tasks.IncrementalTask;
import com.android.builder.png.VectorDrawableRenderer;
import com.android.ide.common.res2.FileStatus;
import com.android.ide.common.res2.MergingException;
import com.android.ide.common.res2.PreprocessDataSet;
import com.android.ide.common.res2.PreprocessResourcesMerger;
import com.android.ide.common.res2.PreprocessResourcesWriter;
import com.android.resources.Density;
import com.google.common.base.Joiner;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import com.google.common.io.Files;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.OutputDirectory;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Map;
/**
* Generates PNGs from Android vector drawable files.
*/
public class PreprocessResourcesTask extends IncrementalTask {
public static final int MIN_SDK = VectorDrawableRenderer.MIN_SDK_WITH_VECTOR_SUPPORT;
private final VectorDrawableRenderer renderer = new VectorDrawableRenderer();
private File outputResDirectory;
private File generatedResDirectory;
private File mergedResDirectory;
private EnumSet densitiesToGenerate;
private String variantName;
@Override
protected boolean isIncremental() {
return true;
}
@Override
protected void doIncrementalTaskAction(Map changedInputs) {
// TODO: Check for changes in the densities.
PreprocessResourcesMerger merger = new PreprocessResourcesMerger();
try {
Files.touch(new File(getIncrementalFolder(), "build_was_incremental"));
if (!merger.loadFromBlob(getIncrementalFolder(), true /*incrementalState*/)) {
doFullTaskAction();
return;
}
if (!merger.getDensities().equals(densitiesToGenerate)) {
getLogger().info("Set of densities for generating PNG files changed, starting from scratch.");
doFullTaskAction();
return;
}
SetMultimap generatedFiles = HashMultimap.create();
for (PreprocessDataSet dataSet : merger.getDataSets()) {
dataSet.setGeneratedResDirectory(getGeneratedResDirectory());
dataSet.setMergedResDirectory(getMergedResDirectory());
dataSet.setGeneratedFiles(generatedFiles);
}
for (Map.Entry entry : changedInputs.entrySet()) {
switch (entry.getValue()) {
case CHANGED: // Fall through.
case NEW:
handleFile(
entry.getKey(),
entry.getValue(),
merger.getMergedDataSet(),
merger.getGeneratedDataSet(),
generatedFiles);
break;
case REMOVED:
merger.getMergedDataSet().updateWith(
getMergedResDirectory(),
entry.getKey(),
FileStatus.REMOVED,
getILogger());
merger.getGeneratedDataSet().updateWith(
getMergedResDirectory(),
entry.getKey(),
FileStatus.REMOVED,
getILogger());
break;
}
}
finalizeMerge(merger);
} catch (MergingException e) {
merger.cleanBlob(getIncrementalFolder());
throw new RuntimeException(e);
} catch (IOException e) {
merger.cleanBlob(getIncrementalFolder());
throw new RuntimeException(e);
}
}
@Override
protected void doFullTaskAction() {
// Maps input files to all files generated from them. This is used by the generated data set
// when it needs to create all data items that come from a given data file.
SetMultimap generatedFiles = HashMultimap.create();
emptyFolder(getOutputResDirectory());
emptyFolder(getGeneratedResDirectory());
emptyFolder(getIncrementalFolder());
PreprocessDataSet mergedSet = new PreprocessDataSet(
getVariantName(),
PreprocessDataSet.ResourcesDirectory.MERGED);
mergedSet.addSource(getMergedResDirectory());
mergedSet.setMergedResDirectory(getMergedResDirectory());
PreprocessDataSet generatedSet = new PreprocessDataSet(
getVariantName(),
PreprocessDataSet.ResourcesDirectory.GENERATED);
generatedSet.addSource(getMergedResDirectory());
generatedSet.setGeneratedResDirectory(getGeneratedResDirectory());
// This map will be updated as we generate more files.
generatedSet.setGeneratedFiles(generatedFiles);
try {
for (File resourceFile : getProject().fileTree(getMergedResDirectory())) {
handleFile(resourceFile, FileStatus.NEW, mergedSet, generatedSet, generatedFiles);
}
PreprocessResourcesMerger merger = new PreprocessResourcesMerger();
merger.setDensities(densitiesToGenerate);
// Files from the merged directory take precedence.
merger.addDataSet(generatedSet);
merger.addDataSet(mergedSet);
finalizeMerge(merger);
} catch (MergingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void finalizeMerge(PreprocessResourcesMerger merger)
throws MergingException {
PreprocessResourcesWriter writer = new PreprocessResourcesWriter(getOutputResDirectory());
merger.mergeData(writer, true);
merger.writeBlobTo(getIncrementalFolder(), writer);
}
private void handleFile(
File resourceFile,
FileStatus fileStatus,
PreprocessDataSet mergedSet,
PreprocessDataSet generatedSet,
SetMultimap generatedFiles) throws IOException, MergingException {
if (renderer.needsPreprocessing(resourceFile)) {
Collection newFiles = renderer.createPngFiles(
resourceFile,
getGeneratedResDirectory(),
getDensitiesToGenerate());
generatedFiles.putAll(resourceFile, newFiles);
generatedSet.updateWith(
getMergedResDirectory(),
resourceFile,
fileStatus,
getILogger());
} else {
mergedSet.updateWith(
getMergedResDirectory(),
resourceFile,
fileStatus,
getILogger());
}
}
/**
* Directory in which to put generated files. They will be then copied to the final destination
* if this would not overwrite anything.
*
* @see #getOutputResDirectory()
*/
@OutputDirectory
public File getGeneratedResDirectory() {
return generatedResDirectory;
}
public void setGeneratedResDirectory(File generatedResDirectory) {
this.generatedResDirectory = generatedResDirectory;
}
/**
* "Input" resource directory, with all resources for the current variant merged.
*/
@InputDirectory
public File getMergedResDirectory() {
return mergedResDirectory;
}
public void setMergedResDirectory(File mergedResDirectory) {
this.mergedResDirectory = mergedResDirectory;
}
/**
* Resources directory that will be passed to aapt.
*/
@OutputDirectory
public File getOutputResDirectory() {
return outputResDirectory;
}
public void setOutputResDirectory(File outputResDirectory) {
this.outputResDirectory = outputResDirectory;
}
public Collection getDensitiesToGenerate() {
return densitiesToGenerate;
}
public void setDensitiesToGenerate(Collection densitiesToGenerate) {
this.densitiesToGenerate = EnumSet.copyOf(densitiesToGenerate);
}
public String getVariantName() {
return variantName;
}
public void setVariantName(String variantName) {
this.variantName = variantName;
}
/**
* Make sure Gradle the task when densities change. {@link Input} doesn't work on collections,
* so we need to use a trick.
*/
@Input
public String getDensitiesFingerprint() {
return Joiner.on(':').join(densitiesToGenerate);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy