package com.gradle import com.android.build.api.transform.* import com.google.common.collect.ImmutableSet import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import org.gradle.api.Project import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging /** * Created by Glen on 2017/2/7. */ public abstract class ModifyClassTransform extends Transform { protected Project project; protected Logger logger; public ModifyClassTransform(Project project) { this.project = project this.logger = Logging.getLogger(ModifyClassTransform.class) } @Override public String getName() { return "Modify" } @Override public Set getInputTypes() { return ImmutableSet.of(QualifiedContent.DefaultContentType.CLASSES) } @Override public Set getScopes() { return ImmutableSet.of( QualifiedContent.Scope.PROJECT,// app class QualifiedContent.Scope.PROJECT_LOCAL_DEPS,// app libs local jar QualifiedContent.Scope.SUB_PROJECTS,//sub lib class QualifiedContent.Scope.SUB_PROJECTS_LOCAL_DEPS,//sub lib libs local jar QualifiedContent.Scope.EXTERNAL_LIBRARIES//compile dependencies ) } @Override public boolean isIncremental() { return true } @Override void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { long time = System.currentTimeMillis() //delete all transformInvocation.outputProvider.deleteAll() // Collecting inputs. transformInvocation.inputs.each { input -> input.directoryInputs.each { dirInput -> if (transformInvocation.incremental) { // 待修复bug // dirInput.changedFiles.each { changedFile -> // handleChangedFile(changedFile.key) // } dirInput.file.eachFileRecurse { File file -> handleChangedFile(file) } } else { dirInput.file.eachFileRecurse { File file -> handleChangedFile(file) } } //output modify class file File file = transformInvocation.outputProvider.getContentLocation(dirInput.file.name, dirInput.contentTypes, dirInput.scopes, Format.DIRECTORY) FileUtils.copyDirectory(dirInput.file, file) } input.jarInputs.each { jarInput -> switch (jarInput.status) { case Status.NOTCHANGED: if (transformInvocation.incremental) break case Status.ADDED: case Status.CHANGED: handleChangedFile(jarInput.file) } //output modify jar file File file = transformInvocation.outputProvider.getContentLocation(getUniqueFileName(jarInput.file), jarInput.contentTypes, jarInput.scopes, Format.JAR) FileUtils.copyFile(jarInput.file, file) } } this.project.logger.error(":" + this.project.name + ":" + getName() + " consume time " + (System.currentTimeMillis() - time) + "ms") } /** * 生成唯一文件名 * @param fileInput * @return */ protected String getUniqueFileName(File fileInput) { final String fileInputName = fileInput.getName() if (fileInput.isDirectory()) { return fileInputName } final String parentDirPath = fileInput.getParentFile().getAbsolutePath() final String pathMD5 = DigestUtils.md5Hex(parentDirPath.getBytes()).substring(0, 6) final int extSepPos = fileInputName.lastIndexOf('.') final String fileInputNamePrefix = (extSepPos >= 0 ? fileInputName.substring(0, extSepPos) : fileInputName) return fileInputNamePrefix + '_' + pathMD5 } /** * logger * @param msg */ protected void debug(def msg) { //this.logger.lifecycle(":" + this.project.name + ":" + msg) } /** * 增量文件 * @param input */ protected abstract void handleChangedFile(File input) }