From 95e4082fe7c8f63e70be8ea5b59fa502aa35b240 Mon Sep 17 00:00:00 2001 From: zjupure Date: Fri, 14 Sep 2018 23:39:55 +0800 Subject: [PATCH 01/10] fix animator res dir not keep in plugin apk when anim and animator both used --- .../src/main/groovy/com.didi.virtualapk/aapt/Aapt.groovy | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/Aapt.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/Aapt.groovy index 8644f0e..2be7bc4 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/Aapt.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/Aapt.groovy @@ -61,7 +61,13 @@ public class Aapt { void filterResources(final List retainedTypes, final Set outFilteredResources) { def resDir = new File(assetDir, 'res') resDir.listFiles().each { typeDir -> - def type = retainedTypes.find { typeDir.name.startsWith(it.name) } + def type = retainedTypes.find { + if (typeDir.name.startsWith("animator")) { + it.name == "animator" + } else { + typeDir.name.startsWith(it.name) + } + } if (type == null) { typeDir.listFiles().each { outFilteredResources.add("res/$typeDir.name/$it.name") From 3e96b843ec0d583e7880e7970cf56af0024e79f5 Mon Sep 17 00:00:00 2001 From: zjupure Date: Fri, 14 Sep 2018 23:46:07 +0800 Subject: [PATCH 02/10] fix plugin build with Android P's buildTools (28.0.+) --- .../groovy/com.didi.virtualapk/aapt/ArscEditor.groovy | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/ArscEditor.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/ArscEditor.groovy index f15e1e3..f75fa63 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/ArscEditor.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/aapt/ArscEditor.groovy @@ -31,13 +31,9 @@ public class ArscEditor extends AssetEditor { private static def LIBRARY_CHUNK_SIZE = 272 // ResTable_lib_header & ResTable_lib_entry private static def TABLE_SIZE_POS = 4 - private int mTableConfigSize = 52 // sizeof(ResTable_config) ArscEditor(File file, def v) { super(file, v) - if (version != null && version.major >= 24) { - mTableConfigSize = 56 - } } /** @@ -661,11 +657,13 @@ public class ArscEditor extends AssetEditor { // c.screenConfig2.screenLayout2 = readByte() // c.screenConfig2.screenConfigPad1 = readByte() // c.screenConfig2.screenConfigPad2 = readShort() - c.ignored = readBytes(mTableConfigSize) + c.size = readInt() + c.ignored = readBytes(c.size - 4) return c } /** Write struct ResTable_config */ def writeTableConfig(c) { + writeInt(c.size) writeBytes(c.ignored) } @@ -682,7 +680,8 @@ public class ArscEditor extends AssetEditor { skip(4) // id(1), res0(1), res1(2) type.entryCount= readInt() type.entriesStart = readInt() - skip(mTableConfigSize) // ResTable_type.config: struct ResTable_config + def size = readInt() + skip(size - 4) // ResTable_type.config: struct ResTable_config } return type } From 40c7631bad0968fef4df6fd2a1690879180057a7 Mon Sep 17 00:00:00 2001 From: lixi Date: Fri, 30 Nov 2018 17:21:33 +0800 Subject: [PATCH 03/10] feat: Supported com.android.tools.build:gradle:3.2.0 --- .../com.didi.virtualapk/BasePlugin.groovy | 15 +++---- .../com.didi.virtualapk/Constants.groovy | 5 --- .../com.didi.virtualapk/VAHostPlugin.groovy | 39 ++++++++-------- .../hooker/MergeAssetsHooker.groovy | 17 ++++--- .../hooker/MergeManifestsHooker.groovy | 25 ++++++----- .../hooker/PrepareDependenciesHooker.groovy | 6 +-- .../hooker/ProcessResourcesHooker.groovy | 41 +++++++++-------- .../com.didi.virtualapk/os/Build.groovy | 44 +++++++++++++++++++ .../support/ScopeCompat.groovy | 30 +++++++++++++ 9 files changed, 143 insertions(+), 79 deletions(-) delete mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/Constants.groovy create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy index 48b896d..1b0336d 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy @@ -7,6 +7,7 @@ import com.android.build.gradle.internal.TaskManager import com.android.build.gradle.internal.api.ApplicationVariantImpl import com.android.build.gradle.internal.variant.VariantFactory import com.android.builder.core.VariantType +import com.didi.virtualapk.os.Build import com.didi.virtualapk.tasks.AssemblePlugin import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect @@ -43,14 +44,8 @@ public abstract class BasePlugin implements Plugin { @Override public void apply(Project project) { this.project = project - project.ext.set(Constants.GRADLE_3_1_0, false) - try { - Class.forName('com.android.builder.core.VariantConfiguration') - } catch (Throwable e) { - // com.android.tools.build:gradle:3.1.0 - project.ext.set(Constants.GRADLE_3_1_0, true) - } + Build.initGradleVersion(project) AppPlugin appPlugin = project.plugins.findPlugin(AppPlugin) @@ -76,7 +71,7 @@ public abstract class BasePlugin implements Plugin { project.extensions.create('virtualApk', VAExtention) - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { TaskManager taskManager = Reflect.on(appPlugin).field('taskManager').get() taskFactory = taskManager.getTaskFactory() } else { @@ -105,7 +100,7 @@ public abstract class BasePlugin implements Plugin { } } - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { taskFactory.configure("assemblePlugin", action) } else { taskFactory.named("assemblePlugin", action) @@ -141,7 +136,7 @@ public abstract class BasePlugin implements Plugin { appPlugin.variantManager.productFlavors.each { String variantName - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { variantName = Reflect.on('com.android.build.gradle.internal.core.VariantConfiguration') .call('computeFullName', it.key, buildType, VariantType.DEFAULT, null) .get() diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/Constants.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/Constants.groovy deleted file mode 100644 index f4eded9..0000000 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/Constants.groovy +++ /dev/null @@ -1,5 +0,0 @@ -package com.didi.virtualapk - -public final class Constants { - public static final String GRADLE_3_1_0 = 'va.gradle.3.1.0' -} \ No newline at end of file diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy index 4df6fa6..17989c9 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy @@ -7,6 +7,7 @@ import com.android.build.gradle.internal.pipeline.TransformTask import com.android.build.gradle.internal.publishing.AndroidArtifacts import com.android.build.gradle.internal.transforms.ProGuardTransform import com.android.build.gradle.tasks.ProcessAndroidResources +import com.didi.virtualapk.os.Build import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect @@ -34,19 +35,13 @@ public class VAHostPlugin implements Plugin { public void apply(Project project) { this.project = project - project.ext.set(Constants.GRADLE_3_1_0, false) - try { - Class.forName('com.android.builder.core.VariantConfiguration') - } catch (Throwable e) { - // com.android.tools.build:gradle:3.1.0 - project.ext.set(Constants.GRADLE_3_1_0, true) - } - + Build.initGradleVersion(project) + //The target project must be a android application module if (!project.plugins.hasPlugin('com.android.application')) { Log.e(TAG, "application required!") - return; + return } vaHostDir = new File(project.getBuildDir(), "VAHost") @@ -97,7 +92,7 @@ public class VAHostPlugin implements Plugin { List deps = new ArrayList() Log.i TAG, "Used compileClasspath: ${applicationVariant.name}" Set compileArtifacts - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') .call('computeBuildMapping', project.gradle) .get() @@ -168,7 +163,7 @@ public class VAHostPlugin implements Plugin { /** * Keep the host app resource id same with last publish, in order to compatible with the published plugin */ - def keepResourceIds(variant) { + def keepResourceIds(variant) { def VIRTUAL_APK_DIR = new File([project.rootDir, 'virtualapk'].join(File.separator)) @@ -202,7 +197,8 @@ public class VAHostPlugin implements Plugin { } - def collectResourceEntries(final File mergeXml, final String projectResDir, final Map typeEntries) { + def collectResourceEntries( + final File mergeXml, final String projectResDir, final Map typeEntries) { collectAarResourceEntries(null, projectResDir, mergeXml, typeEntries) @@ -211,14 +207,15 @@ public class VAHostPlugin implements Plugin { project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each { if (it.extension == 'aar') { def moduleVersion = it.moduleVersion.id - def resPath = new File(aarDir,"${moduleVersion.group}/${moduleVersion.name}/${moduleVersion.version}/res") + def resPath = new File(aarDir, "${moduleVersion.group}/${moduleVersion.name}/${moduleVersion.version}/res") collectAarResourceEntries(moduleVersion.version, resPath.path, mergeXml, typeEntries) } } } - def collectAarResourceEntries(String aarVersion, String resPath, File mergeXml, final Map typeEntries) { + def collectAarResourceEntries(String aarVersion, String resPath, File mergeXml, + final Map typeEntries) { final def merger = new XmlParser().parse(mergeXml) def filter = aarVersion == null ? { it.@config == 'main' || it.@config == 'release' @@ -244,9 +241,9 @@ public class VAHostPlugin implements Plugin { def name = it.@name if (type.endsWith('-array')) { type = 'array' - } else if (type == 'item'){ + } else if (type == 'item') { type = it.@type - } else if (type == 'declare-styleable'){ + } else if (type == 'declare-styleable') { return } def entrySet = getEntriesSet(type, typeEntries) @@ -280,20 +277,20 @@ public class VAHostPlugin implements Plugin { } if (type == 'style') { if (styleNameMap.containsKey(values[2])) { - pw.println "\t" + pw.println "\t" } return } //ID does not filter and remains redundant if (type == 'id') { - pw.println "\t" + pw.println "\t" return } //Only keep resources' Id that are present in the current project Set entries = hostResourceEntries[type] if (entries != null && entries.contains(values[2])) { - pw.println "\t" + pw.println "\t" } else { if (entries == null) { if (type != lastSplitType) { @@ -302,7 +299,7 @@ public class VAHostPlugin implements Plugin { } } else { - if (type != 'attr'){ + if (type != 'attr') { println ">>>> ${type} : ${values[2]} is deleted" } @@ -328,7 +325,7 @@ public class VAHostPlugin implements Plugin { } - def Set getEntriesSet (final String type, final Map typeEntries) { + def Set getEntriesSet(final String type, final Map typeEntries) { def entries = typeEntries[type] if (entries == null) { entries = [] as Set diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeAssetsHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeAssetsHooker.groovy index 8b4ef5f..110f856 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeAssetsHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeAssetsHooker.groovy @@ -2,7 +2,6 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant import com.android.build.gradle.tasks.MergeSourceSetFolders -import com.android.ide.common.res2.AssetSet import com.didi.virtualapk.collector.dependence.AarDependenceInfo import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect @@ -42,31 +41,31 @@ class MergeAssetsHooker extends GradleTaskHooker { } Reflect reflect = Reflect.on(task) - reflect.set('assetSetSupplier', new FixedSupplier(this, reflect.get('assetSetSupplier'), strippedAssetPaths)) + reflect.set('assetSetSupplier', new FixedSupplier<>(this, reflect.get('assetSetSupplier'), strippedAssetPaths)) } @Override void afterTaskExecute(MergeSourceSetFolders task) { } - static class FixedSupplier implements Supplier> { + static class FixedSupplier implements Supplier> { MergeAssetsHooker hooker - Supplier> origin + Supplier> origin Set strippedAssetPaths - FixedSupplier(MergeAssetsHooker hooker, Supplier> origin, Set strippedAssetPaths) { + FixedSupplier(MergeAssetsHooker hooker, Supplier> origin, Set strippedAssetPaths) { this.hooker = hooker this.origin = origin this.strippedAssetPaths = strippedAssetPaths } @Override - List get() { - List assetSets = origin.get() - assetSets.removeIf(new Predicate() { + List get() { + List assetSets = origin.get() + assetSets.removeIf(new Predicate() { @Override - boolean test(AssetSet assetSet) { + boolean test(T assetSet) { boolean ret = strippedAssetPaths.contains(assetSet.sourceFiles.get(0).path) if (ret) { Log.i 'MergeAssetsHooker', "Stripped asset of artifact: ${assetSet} -> ${assetSet.sourceFiles.get(0).path}" diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy index cdd23fa..065a8c1 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy @@ -1,10 +1,10 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant -import com.android.build.gradle.internal.scope.TaskOutputHolder import com.android.build.gradle.tasks.MergeManifests -import com.didi.virtualapk.Constants +import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.DependenceInfo +import com.didi.virtualapk.support.ScopeCompat import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect import groovy.xml.QName @@ -58,27 +58,28 @@ class MergeManifestsHooker extends GradleTaskHooker { */ @Override void afterTaskExecute(MergeManifests task) { - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { - File outputFile = Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') - .call('from', TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS, scope.getOutput(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS)) - .call('element', variantData.outputScope.mainSplit) + def MERGED_MANIFESTS = ScopeCompat.getArtifact(project, "MERGED_MANIFESTS") + if (Build.isSupportVersion(project,Build.VERSION_CODE.V3_1_X)) { + File outputFile = (Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') + .call('from', MERGED_MANIFESTS, ScopeCompat.getArtifactFile(scope, project, MERGED_MANIFESTS)) + .call('element', variantData.outputScope.mainSplit)) .call('getOutputFile') .get() rewrite(outputFile) } else { - variantData.outputScope.getOutputs(TaskOutputHolder.TaskOutputType.MERGED_MANIFESTS).each { + variantData.outputScope.getOutputs(MERGED_MANIFESTS).each { rewrite(it.outputFile) } } } - + void rewrite(File xml) { if (xml?.exists()) { final Node manifest = new XmlParser().parse(xml) manifest.application.each { application -> - [ 'icon', 'label', 'allowBackup', 'supportsRtl' ].each { + ['icon', 'label', 'allowBackup', 'supportsRtl'].each { application.attributes().remove(new QName(MergeManifestsHooker.ANDROID_NAMESPACE, it)) } } @@ -88,13 +89,13 @@ class MergeManifestsHooker extends GradleTaskHooker { }) } } - + private static class FixedArtifactCollection implements ArtifactCollection { private MergeManifestsHooker hooker private ArtifactCollection origin def stripAarNames - + FixedArtifactCollection(MergeManifestsHooker hooker, ArtifactCollection origin, stripAarNames) { this.hooker = hooker this.origin = origin @@ -166,4 +167,4 @@ class MergeManifestsHooker extends GradleTaskHooker { return getArtifacts().spliterator() } } -} \ No newline at end of file +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy index c624e5c..67fcbb3 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy @@ -5,7 +5,7 @@ import com.android.build.gradle.internal.ide.ArtifactDependencyGraph import com.android.build.gradle.internal.tasks.AppPreBuildTask import com.android.builder.model.Dependencies import com.android.builder.model.SyncIssue -import com.didi.virtualapk.Constants +import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.AarDependenceInfo import com.didi.virtualapk.collector.dependence.DependenceInfo import com.didi.virtualapk.collector.dependence.JarDependenceInfo @@ -70,7 +70,7 @@ class PrepareDependenciesHooker extends GradleTaskHooker { } } Dependencies dependencies - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') .call('computeBuildMapping', project.gradle) .get() @@ -169,4 +169,4 @@ class PrepareDependenciesHooker extends GradleTaskHooker { throw new Exception("The dependencies [${String.join(', ', checked)}] that will be used in the current plugin must be included in the host app first. Please add it in the host app as well.") } } -} \ No newline at end of file +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy index e75a1ef..d66a9e6 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy @@ -3,14 +3,15 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.AndroidConfig import com.android.build.gradle.AppExtension import com.android.build.gradle.api.ApkVariant -import com.android.build.gradle.internal.scope.TaskOutputHolder import com.android.build.gradle.tasks.ProcessAndroidResources import com.android.sdklib.BuildToolInfo -import com.didi.virtualapk.Constants +import com.didi.virtualapk.os.Build import com.didi.virtualapk.aapt.Aapt import com.didi.virtualapk.collector.ResourceCollector import com.didi.virtualapk.collector.res.ResourceEntry import com.didi.virtualapk.collector.res.StyleableEntry +import com.didi.virtualapk.support.ScopeCompat + import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect @@ -59,15 +60,17 @@ class ProcessResourcesHooker extends GradleTaskHooker { */ @Override void afterTaskExecute(ProcessAndroidResources par) { - if (project.extensions.extraProperties.get(Constants.GRADLE_3_1_0)) { + + def PROCESSED_RES = ScopeCompat.getArtifact(project, "PROCESSED_RES") + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { File outputFile = Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') - .call('from', TaskOutputHolder.TaskOutputType.PROCESSED_RES, scope.getOutput(TaskOutputHolder.TaskOutputType.PROCESSED_RES)) + .call('from', PROCESSED_RES, ScopeCompat.getArtifactFile(scope, project, PROCESSED_RES)) .call('element', variantData.outputScope.mainSplit) .call('getOutputFile') .get() repackage(par, outputFile) } else { - variantData.outputScope.getOutputs(TaskOutputHolder.TaskOutputType.PROCESSED_RES).each { + variantData.outputScope.getOutputs(PROCESSED_RES).each { repackage(par, it.outputFile) } } @@ -198,18 +201,18 @@ class ProcessResourcesHooker extends GradleTaskHooker { pluginResources.keySet().each { resType -> def firstEntry = pluginResources.get(resType).get(0) - def typeEntry = [ type: "int", name: resType, - id: parseTypeIdFromResId(firstEntry.resourceId), - _id: parseTypeIdFromResId(firstEntry.newResourceId), - entries: []] + def typeEntry = [type : "int", name: resType, + id : parseTypeIdFromResId(firstEntry.resourceId), + _id : parseTypeIdFromResId(firstEntry.newResourceId), + entries: []] pluginResources.get(resType).each { resEntry -> typeEntry.entries.add([ - name : resEntry.resourceName, - id : parseEntryIdFromResId(resEntry.resourceId), - _id: parseEntryIdFromResId(resEntry.newResourceId), - v : resEntry.resourceId, _v : resEntry.newResourceId, - vs: resEntry.hexResourceId, _vs : resEntry.hexNewResourceId]) + name: resEntry.resourceName, + id : parseEntryIdFromResId(resEntry.resourceId), + _id : parseEntryIdFromResId(resEntry.newResourceId), + v : resEntry.resourceId, _v: resEntry.newResourceId, + vs : resEntry.hexResourceId, _vs: resEntry.hexNewResourceId]) } retainedTypes.add(typeEntry) @@ -218,7 +221,7 @@ class ProcessResourcesHooker extends GradleTaskHooker { retainedTypes.sort { t1, t2 -> t1._id - t2._id } - + return retainedTypes } @@ -229,10 +232,10 @@ class ProcessResourcesHooker extends GradleTaskHooker { def convertStyleablesForAapt(List pluginStyleables) { def retainedStyleables = [] pluginStyleables.each { styleableEntry -> - retainedStyleables.add([vtype : styleableEntry.valueType, + retainedStyleables.add([vtype: styleableEntry.valueType, type : 'styleable', - key : styleableEntry.name, - idStr : styleableEntry.value]) + key : styleableEntry.name, + idStr: styleableEntry.value]) } return retainedStyleables } @@ -251,4 +254,4 @@ class ProcessResourcesHooker extends GradleTaskHooker { resourceId & 0xFFFF } -} \ No newline at end of file +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy new file mode 100644 index 0000000..f688058 --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy @@ -0,0 +1,44 @@ +package com.didi.virtualapk.os + +import org.gradle.api.Project + +final class Build { + + public static final String GRADLE_VERSION_SDK_INT = 'va.gradle.version.sdk_int' + + static interface VERSION_CODE { + int NONE = 0 + int V3_1_X = 310 + int V3_2_X = 320 + } + + static void initGradleVersion(Project project) { + if (findClass("com.android.build.gradle.internal.scope.InternalArtifactType")) { + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_2_X) + return + } + + if (!findClass("com.android.builder.core.VariantConfiguration")) { + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_1_X) + return + } + + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.NONE) + } + + + private static findClass(String className) { + try { + Class.forName(className) + return true + } catch (Throwable ignored) { + return false + } + } + + + static boolean isSupportVersion(Project project, int minVersion) { + return project.extensions.extraProperties.get(GRADLE_VERSION_SDK_INT) >= minVersion + } + +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy new file mode 100644 index 0000000..0aa594d --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy @@ -0,0 +1,30 @@ +package com.didi.virtualapk.support + +import com.android.build.gradle.internal.scope.VariantScope +import com.didi.virtualapk.os.Build +import com.didi.virtualapk.utils.Reflect +import org.gradle.api.Project + +final class ScopeCompat { + + + def static getArtifact(Project project, String name) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { + return Reflect.on("com.android.build.gradle.internal.scope.InternalArtifactType") + .field(name).get() + } else { + return Reflect.on("com.android.build.gradle.internal.scope.TaskOutputHolder\$TaskOutputType") + .field(name).get() + } + } + + + def static getArtifactFile(VariantScope scope, Project project, def artifact) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { + return scope.artifacts.getFinalArtifactFiles(artifact) + } else { + return scope.getOutput(artifact) + } + } + +} From cf3db1b40b68ef34f883ff686a301ad2101afbc9 Mon Sep 17 00:00:00 2001 From: superq_sky Date: Tue, 8 Jan 2019 20:44:49 +0800 Subject: [PATCH 04/10] Updated the version. --- virtualapk-gradle-plugin/gradle.properties | 2 +- .../src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/virtualapk-gradle-plugin/gradle.properties b/virtualapk-gradle-plugin/gradle.properties index 69c33d6..3a20ab3 100644 --- a/virtualapk-gradle-plugin/gradle.properties +++ b/virtualapk-gradle-plugin/gradle.properties @@ -1,3 +1,3 @@ GROUP_ID=com.didi.virtualapk ARTIFACT_ID=gradle -VERSION=0.9.8.5.1-dev +VERSION=0.9.8.5.2-dev diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy index 17989c9..ac4a53e 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy @@ -197,8 +197,7 @@ public class VAHostPlugin implements Plugin { } - def collectResourceEntries( - final File mergeXml, final String projectResDir, final Map typeEntries) { + def collectResourceEntries(final File mergeXml, final String projectResDir, final Map typeEntries) { collectAarResourceEntries(null, projectResDir, mergeXml, typeEntries) @@ -214,8 +213,7 @@ public class VAHostPlugin implements Plugin { } - def collectAarResourceEntries(String aarVersion, String resPath, File mergeXml, - final Map typeEntries) { + def collectAarResourceEntries(String aarVersion, String resPath, File mergeXml, final Map typeEntries) { final def merger = new XmlParser().parse(mergeXml) def filter = aarVersion == null ? { it.@config == 'main' || it.@config == 'release' From 9c8f8f6191401c276d012d8e9aef60771577f672 Mon Sep 17 00:00:00 2001 From: superq_sky Date: Tue, 8 Jan 2019 20:51:41 +0800 Subject: [PATCH 05/10] Updated the version. --- PluginDemo/build.gradle | 2 +- build.gradle | 2 +- virtualapk-gradle-plugin/gradle.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PluginDemo/build.gradle b/PluginDemo/build.gradle index 0d837ab..63529fc 100644 --- a/PluginDemo/build.gradle +++ b/PluginDemo/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' - classpath 'com.didi.virtualapk:gradle:0.9.8.5.1-dev' + classpath 'com.didi.virtualapk:gradle:0.9.8.6.2-dev' } } diff --git a/build.gradle b/build.gradle index a531b33..c734d09 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.0.0' - classpath 'com.didi.virtualapk:gradle:0.9.8.5.1-dev' + classpath 'com.didi.virtualapk:gradle:0.9.8.6.2-dev' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' diff --git a/virtualapk-gradle-plugin/gradle.properties b/virtualapk-gradle-plugin/gradle.properties index 3a20ab3..202394f 100644 --- a/virtualapk-gradle-plugin/gradle.properties +++ b/virtualapk-gradle-plugin/gradle.properties @@ -1,3 +1,3 @@ GROUP_ID=com.didi.virtualapk ARTIFACT_ID=gradle -VERSION=0.9.8.5.2-dev +VERSION=0.9.8.6.2-dev From 8ea225968295f5551dde0544c27cbf25c16d2967 Mon Sep 17 00:00:00 2001 From: superq_sky Date: Tue, 14 May 2019 11:10:42 +0800 Subject: [PATCH 06/10] Marked plugin infos by intent categories. --- .../internal/ComponentsHandler.java | 13 ++++++--- .../didi/virtualapk/internal/Constants.java | 11 +++++--- .../internal/VAInstrumentation.java | 3 ++- .../virtualapk/internal/utils/PluginUtil.java | 27 ++++++++++++++++--- CoreLibrary/upload.gradle | 2 +- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/ComponentsHandler.java b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/ComponentsHandler.java index 85ad067..2e76229 100644 --- a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/ComponentsHandler.java +++ b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/ComponentsHandler.java @@ -29,6 +29,8 @@ import com.didi.virtualapk.PluginManager; +import java.util.ArrayList; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** @@ -79,9 +81,14 @@ public void markIntentIfNeeded(Intent intent) { String targetClassName = intent.getComponent().getClassName(); // search map and return specific launchmode stub activity if (!targetPackageName.equals(mContext.getPackageName()) && mPluginManager.getLoadedPlugin(targetPackageName) != null) { - intent.putExtra(Constants.KEY_IS_PLUGIN, true); - intent.putExtra(Constants.KEY_TARGET_PACKAGE, targetPackageName); - intent.putExtra(Constants.KEY_TARGET_ACTIVITY, targetClassName); + // mark plugin by categories + Set categories = intent.getCategories(); + if (categories != null) { + intent.putStringArrayListExtra(Constants.KEY_CATEGORY, new ArrayList<>(categories)); + categories.clear(); + } + intent.addCategory(Constants.CATEGORY_PREFIX_TARGET_PACKAGE + targetPackageName); + intent.addCategory(Constants.CATEGORY_PREFIX_TARGET_ACTIVITY + targetClassName); dispatchStubActivity(intent); } } diff --git a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/Constants.java b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/Constants.java index b139f77..98d2f27 100644 --- a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/Constants.java +++ b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/Constants.java @@ -20,9 +20,14 @@ * Created by renyugang on 16/8/15. */ public class Constants { - public static final String KEY_IS_PLUGIN = "isPlugin"; - public static final String KEY_TARGET_PACKAGE = "target.package"; - public static final String KEY_TARGET_ACTIVITY = "target.activity"; + public static final String KEY_CATEGORY = "va.intent.extra.category"; + public static final String CATEGORY_PREFIX = "va.intent.category."; + public static final String CATEGORY_PREFIX_TARGET_PACKAGE = CATEGORY_PREFIX + "package."; + public static final String CATEGORY_PREFIX_TARGET_ACTIVITY = CATEGORY_PREFIX + "activity."; + +// public static final String KEY_IS_PLUGIN = "isPlugin"; +// public static final String KEY_TARGET_PACKAGE = "target.package"; +// public static final String KEY_TARGET_ACTIVITY = "target.activity"; public static final String OPTIMIZE_DIR = "dex"; public static final String NATIVE_DIR = "valibs"; diff --git a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java index 1ec0802..d7c6dd9 100644 --- a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java +++ b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/VAInstrumentation.java @@ -184,6 +184,7 @@ protected void injectActivity(Activity activity) { ComponentName component = PluginUtil.getComponent(intent); Intent wrapperIntent = new Intent(intent); wrapperIntent.setClassName(component.getPackageName(), component.getClassName()); + wrapperIntent.setExtrasClassLoader(activity.getClassLoader()); activity.setIntent(wrapperIntent); } catch (Exception e) { @@ -200,7 +201,7 @@ public boolean handleMessage(Message msg) { try { Reflector reflector = Reflector.with(r); Intent intent = reflector.field("intent").get(); - intent.setExtrasClassLoader(mPluginManager.getHostContext().getClassLoader()); +// intent.setExtrasClassLoader(mPluginManager.getHostContext().getClassLoader()); ActivityInfo activityInfo = reflector.field("activityInfo").get(); if (PluginUtil.isIntentFromPlugin(intent)) { diff --git a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java index a1eea83..e94e191 100644 --- a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java +++ b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java @@ -59,18 +59,37 @@ public static ComponentName getComponent(Intent intent) { return null; } if (isIntentFromPlugin(intent)) { - return new ComponentName(intent.getStringExtra(Constants.KEY_TARGET_PACKAGE), - intent.getStringExtra(Constants.KEY_TARGET_ACTIVITY)); + String pkg = null; + String activity = null; + for (String cat : intent.getCategories()) { + if (cat.startsWith(Constants.CATEGORY_PREFIX_TARGET_PACKAGE)) { + pkg = cat.substring(Constants.CATEGORY_PREFIX_TARGET_PACKAGE.length()); + continue; + } + + if (cat.startsWith(Constants.CATEGORY_PREFIX_TARGET_ACTIVITY)) { + activity = cat.substring(Constants.CATEGORY_PREFIX_TARGET_ACTIVITY.length()); + continue; + } + } + return new ComponentName(pkg, activity); } return intent.getComponent(); } public static boolean isIntentFromPlugin(Intent intent) { - if (intent == null) { + if (intent == null || intent.getCategories() == null) { return false; } - return intent.getBooleanExtra(Constants.KEY_IS_PLUGIN, false); + + for (String cat : intent.getCategories()) { + if (cat.startsWith(Constants.KEY_CATEGORY)) { + return true; + } + } + + return false; } public static int getTheme(Context context, Intent intent) { diff --git a/CoreLibrary/upload.gradle b/CoreLibrary/upload.gradle index f8cbcd7..dd677c5 100644 --- a/CoreLibrary/upload.gradle +++ b/CoreLibrary/upload.gradle @@ -11,7 +11,7 @@ def gitUrl = 'https://github.com/didi/VirtualAPK' // Git仓库的url group = GROUP_ID archivesBaseName = 'core' -version = "0.9.7.1" +version = "0.9.9.0-dev" install { From fc7cbba4341e6e8155faa95c497f3c7782b4f64d Mon Sep 17 00:00:00 2001 From: superq_sky Date: Tue, 14 May 2019 13:18:33 +0800 Subject: [PATCH 07/10] FixBug: used the wrong key. --- .../java/com/didi/virtualapk/internal/utils/PluginUtil.java | 2 +- CoreLibrary/upload.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java index e94e191..65a51d7 100644 --- a/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java +++ b/CoreLibrary/src/main/java/com/didi/virtualapk/internal/utils/PluginUtil.java @@ -84,7 +84,7 @@ public static boolean isIntentFromPlugin(Intent intent) { } for (String cat : intent.getCategories()) { - if (cat.startsWith(Constants.KEY_CATEGORY)) { + if (cat.startsWith(Constants.CATEGORY_PREFIX)) { return true; } } diff --git a/CoreLibrary/upload.gradle b/CoreLibrary/upload.gradle index dd677c5..ba7fe2a 100644 --- a/CoreLibrary/upload.gradle +++ b/CoreLibrary/upload.gradle @@ -11,7 +11,7 @@ def gitUrl = 'https://github.com/didi/VirtualAPK' // Git仓库的url group = GROUP_ID archivesBaseName = 'core' -version = "0.9.9.0-dev" +version = "0.9.9.1-dev" install { From 9e38048d00469a1cf318583ac357814f107a2d16 Mon Sep 17 00:00:00 2001 From: superq_sky Date: Tue, 14 May 2019 13:28:18 +0800 Subject: [PATCH 08/10] Updated demo config. --- PluginDemo/app/build.gradle | 2 +- app/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PluginDemo/app/build.gradle b/PluginDemo/app/build.gradle index b169f9e..c7d16d6 100644 --- a/PluginDemo/app/build.gradle +++ b/PluginDemo/app/build.gradle @@ -54,7 +54,7 @@ dependencies { // the following aars are also compiled in host project, so they will be filterd when build plugin apk. // but, wo can still visit their Class and Resources. implementation 'com.android.support:appcompat-v7:23.4.0' - implementation 'com.didi.virtualapk:core:0.9.6' + implementation 'com.didi.virtualapk:0.9.9.1-dev' } apply plugin: 'com.didi.virtualapk.plugin' diff --git a/app/build.gradle b/app/build.gradle index 08f829b..52a39ea 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -49,7 +49,7 @@ dependencies { testImplementation 'junit:junit:4.12' implementation 'com.android.support:appcompat-v7:23.4.0' - implementation 'com.didi.virtualapk:core:0.9.7-dev' + implementation 'com.didi.virtualapk:core:0.9.9.1-dev' // implementation project (':CoreLibrary') } \ No newline at end of file From 4da000ce8e0a920c6fcd1dbf17f690fd525e67b6 Mon Sep 17 00:00:00 2001 From: panzhihui Date: Tue, 28 May 2019 17:55:36 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E6=94=AF=E6=8C=81agp3.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PluginDemo/app/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../com.didi.virtualapk/BasePlugin.groovy | 65 +++++---------- .../com.didi.virtualapk/VAHostPlugin.groovy | 43 +++++----- .../com.didi.virtualapk/VAPlugin.groovy | 8 +- .../dependence/AarDependenceInfo.groovy | 15 +++- .../hooker/MergeManifestsHooker.groovy | 12 +-- .../hooker/PrepareDependenciesHooker.groovy | 26 +----- .../hooker/ProcessResourcesHooker.groovy | 2 +- .../com.didi.virtualapk/os/Build.groovy | 52 +++++------- .../ArtifactDependencyGraphCompat.groovy | 83 +++++++++++++++++++ .../support/CompatUtil.groovy | 11 +++ .../support/ResolvedArtifactCompat.groovy | 43 ++++++++++ .../support/ScopeCompat.groovy | 4 +- .../support/TaskFactoryCompat.groovy | 43 ++++++++++ 16 files changed, 279 insertions(+), 134 deletions(-) create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy create mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy diff --git a/PluginDemo/app/build.gradle b/PluginDemo/app/build.gradle index c7d16d6..120e5c8 100644 --- a/PluginDemo/app/build.gradle +++ b/PluginDemo/app/build.gradle @@ -54,7 +54,7 @@ dependencies { // the following aars are also compiled in host project, so they will be filterd when build plugin apk. // but, wo can still visit their Class and Resources. implementation 'com.android.support:appcompat-v7:23.4.0' - implementation 'com.didi.virtualapk:0.9.9.1-dev' + implementation 'com.didi.virtualapk:core:0.9.9.1-dev' } apply plugin: 'com.didi.virtualapk.plugin' diff --git a/PluginDemo/gradle/wrapper/gradle-wrapper.properties b/PluginDemo/gradle/wrapper/gradle-wrapper.properties index c3510d6..cb97588 100644 --- a/PluginDemo/gradle/wrapper/gradle-wrapper.properties +++ b/PluginDemo/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 57a9bdc..5c6313c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy index 1b0336d..4666958 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy @@ -2,15 +2,14 @@ package com.didi.virtualapk import com.android.build.gradle.AppExtension import com.android.build.gradle.AppPlugin -import com.android.build.gradle.internal.TaskFactory -import com.android.build.gradle.internal.TaskManager import com.android.build.gradle.internal.api.ApplicationVariantImpl +import com.android.build.gradle.internal.scope.VariantScope import com.android.build.gradle.internal.variant.VariantFactory -import com.android.builder.core.VariantType -import com.didi.virtualapk.os.Build +import com.didi.virtualapk.support.TaskFactoryCompat import com.didi.virtualapk.tasks.AssemblePlugin import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect +import groovy.transform.TypeChecked import org.gradle.api.Action import org.gradle.api.Plugin import org.gradle.api.Project @@ -32,7 +31,7 @@ public abstract class BasePlugin implements Plugin { protected Project project protected Instantiator instantiator - protected TaskFactory taskFactory + def taskFactory boolean checkVariantFactoryInvoked @@ -45,8 +44,6 @@ public abstract class BasePlugin implements Plugin { public void apply(Project project) { this.project = project - Build.initGradleVersion(project) - AppPlugin appPlugin = project.plugins.findPlugin(AppPlugin) Reflect reflect = Reflect.on(appPlugin.variantManager) @@ -71,14 +68,7 @@ public abstract class BasePlugin implements Plugin { project.extensions.create('virtualApk', VAExtention) - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { - TaskManager taskManager = Reflect.on(appPlugin).field('taskManager').get() - taskFactory = taskManager.getTaskFactory() - } else { - taskFactory = Reflect.on('com.android.build.gradle.internal.TaskContainerAdaptor') - .create(project.tasks) - .get() - } + taskFactory = TaskFactoryCompat.getTaskFactory(appPlugin, project) project.afterEvaluate { if (!checkVariantFactoryInvoked) { @@ -91,7 +81,7 @@ public abstract class BasePlugin implements Plugin { def final variantPluginTaskName = createPluginTaskName(variantAssembleTaskName) final def configAction = new AssemblePlugin.ConfigAction(project, variant) - taskFactory.create(variantPluginTaskName, AssemblePlugin, configAction) + TaskFactoryCompat.add(taskFactory, variantPluginTaskName, AssemblePlugin, configAction) Action action = new Action() { @Override @@ -100,11 +90,7 @@ public abstract class BasePlugin implements Plugin { } } - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { - taskFactory.configure("assemblePlugin", action) - } else { - taskFactory.named("assemblePlugin", action) - } + TaskFactoryCompat.configure(taskFactory, "assemblePlugin", action) } } } @@ -119,35 +105,19 @@ public abstract class BasePlugin implements Plugin { return name.replace('Release', '') } + /** + * 通过启动命令判断是否要运行的是是打插件包的 Task + */ private boolean evaluateBuildingPlugin(AppPlugin appPlugin, Project project) { def startParameter = project.gradle.startParameter def targetTasks = startParameter.taskNames def pluginTasks = ['assemblePlugin'] as List - appPlugin.variantManager.buildTypes.each { - def buildType = it.value.buildType - if ('release' != buildType.name) { - return - } - if (appPlugin.variantManager.productFlavors.isEmpty()) { - return - } - - appPlugin.variantManager.productFlavors.each { - String variantName - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { - variantName = Reflect.on('com.android.build.gradle.internal.core.VariantConfiguration') - .call('computeFullName', it.key, buildType, VariantType.DEFAULT, null) - .get() - } else { - variantName = Reflect.on('com.android.builder.core.VariantConfiguration') - .call('computeFullName', it.key, buildType, VariantType.DEFAULT, null) - .get() - } - def variantPluginTaskName = createPluginTaskName("assemble${variantName.capitalize()}Plugin".toString()) - pluginTasks.add(variantPluginTaskName) - } + if (!appPlugin.variantManager.productFlavors.isEmpty()) { + appPlugin.variantManager.variantScopes + .findAll { it.variantConfiguration.buildType.name == "release" } + .forEach { VariantScope scope -> addTaskToListForScope(scope, pluginTasks) } } // pluginTasks.each { @@ -171,6 +141,13 @@ public abstract class BasePlugin implements Plugin { return isBuildingPlugin } + @TypeChecked + private void addTaskToListForScope(VariantScope scope, List pluginTasks) { + String variantName = scope.fullVariantName + def variantPluginTaskName = createPluginTaskName("assemble${variantName.capitalize()}Plugin".toString()) + pluginTasks.add(variantPluginTaskName) + } + protected abstract void beforeCreateAndroidTasks(boolean isBuildingPlugin) protected final VAExtention getVirtualApk() { diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy index ac4a53e..945a330 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy @@ -1,17 +1,16 @@ package com.didi.virtualapk + import com.android.build.gradle.api.ApplicationVariant import com.android.build.gradle.internal.api.ApplicationVariantImpl -import com.android.build.gradle.internal.ide.ArtifactDependencyGraph import com.android.build.gradle.internal.pipeline.TransformTask -import com.android.build.gradle.internal.publishing.AndroidArtifacts import com.android.build.gradle.internal.transforms.ProGuardTransform import com.android.build.gradle.tasks.ProcessAndroidResources +import com.didi.virtualapk.support.ArtifactDependencyGraphCompat +import com.didi.virtualapk.support.ResolvedArtifactCompat import com.didi.virtualapk.os.Build import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log -import com.didi.virtualapk.utils.Reflect -import com.google.common.collect.ImmutableMap import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.component.ComponentIdentifier @@ -36,14 +35,14 @@ public class VAHostPlugin implements Plugin { this.project = project - Build.initGradleVersion(project) - //The target project must be a android application module if (!project.plugins.hasPlugin('com.android.application')) { Log.e(TAG, "application required!") return } + Log.i(TAG, "android gradle plugin version is " + Build.AGP_VERSION) + vaHostDir = new File(project.getBuildDir(), "VAHost") project.afterEvaluate { @@ -91,28 +90,20 @@ public class VAHostPlugin implements Plugin { FileUtil.saveFile(vaHostDir, "versions", { List deps = new ArrayList() Log.i TAG, "Used compileClasspath: ${applicationVariant.name}" - Set compileArtifacts - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { - ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') - .call('computeBuildMapping', project.gradle) - .get() - compileArtifacts = ArtifactDependencyGraph.getAllArtifacts( - applicationVariant.variantData.scope, AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, null, buildMapping) - } else { - compileArtifacts = ArtifactDependencyGraph.getAllArtifacts( - applicationVariant.variantData.scope, AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, null) - } + Set compileArtifacts = ArtifactDependencyGraphCompat.getAllArtifacts(project, applicationVariant) - compileArtifacts.each { ArtifactDependencyGraph.HashableResolvedArtifactResult artifact -> - ComponentIdentifier id = artifact.id.componentIdentifier + compileArtifacts.each { artifact -> + // artifact 在 3.3 以上是 com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact + // artifact 在 3.3 以下是 org.gradle.api.artifacts.result.ResolvedArtifactResult + ComponentIdentifier id = ResolvedArtifactCompat.getComponentIdentifier(artifact) if (id instanceof ProjectComponentIdentifier) { - deps.add("${id.projectPath.replace(':', '')}:${ArtifactDependencyGraph.getVariant(artifact)}:unspecified ${artifact.file.length()}") - + deps.add("${id.projectPath.replace(':', '')}" + + ":${ResolvedArtifactCompat.getVariantName(artifact)}" + + ":unspecified ${getArtifactFileLength(artifact)}") } else if (id instanceof ModuleComponentIdentifier) { - deps.add("${id.group}:${id.module}:${id.version} ${artifact.file.length()}") - + deps.add("${id.group}:${id.module}:${id.version} ${getArtifactFileLength(artifact)}") } else { - deps.add("${artifact.id.displayName.replace(':', '')}:unspecified:unspecified ${artifact.file.length()}") +// deps.add("${id.displayName.replace(':', '')}:unspecified:unspecified ${getArtifactFileLength(artifact)}") } } @@ -123,6 +114,10 @@ public class VAHostPlugin implements Plugin { } + private long getArtifactFileLength(artifact){ + return ResolvedArtifactCompat.getFile(artifact).length() + } + /** * Save R symbol file */ diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy index 93fd8e5..c6661bf 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy @@ -5,6 +5,7 @@ import com.android.build.gradle.internal.api.ApplicationVariantImpl import com.android.build.gradle.options.BooleanOption import com.android.build.gradle.options.ProjectOptions import com.didi.virtualapk.hooker.* +import com.didi.virtualapk.os.Build import com.didi.virtualapk.transform.StripClassAndResTransform import com.didi.virtualapk.utils.FileBinaryCategory import com.didi.virtualapk.utils.Log @@ -227,8 +228,11 @@ class VAPlugin extends BasePlugin { AppPlugin appPlugin = project.plugins.findPlugin(AppPlugin) ProjectOptions projectOptions = Reflect.on(appPlugin).field('projectOptions').get() - if (projectOptions.get(BooleanOption.ENABLE_DEX_ARCHIVE)) { - throw new InvalidUserDataException("Can't using incremental dexing mode, please add 'android.useDexArchive=false' in gradle.properties of :${project.name}.") + // 330 此处已经无效了,永远为 true + if (!Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)){ + if (projectOptions.get(BooleanOption.ENABLE_DEX_ARCHIVE)) { + throw new InvalidUserDataException("Can't using incremental dexing mode, please add 'android.useDexArchive=false' in gradle.properties of :${project.name}.") + } } // project.ext.set('android.useDexArchive', false) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy index 94ab3f3..b501e91 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy @@ -6,6 +6,7 @@ import com.android.builder.model.AndroidLibrary import com.android.utils.FileUtils import com.didi.virtualapk.collector.res.ResourceEntry import com.didi.virtualapk.collector.res.StyleableEntry +import com.didi.virtualapk.os.Build import com.didi.virtualapk.utils.Log import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap @@ -98,12 +99,24 @@ class AarDependenceInfo extends DependenceInfo { * @return package name of this library */ public String getPackage() { - File manifest = getFile(library.manifest, 'manifests', 'full', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) + File manifest = getLibManifestFile() Log.i 'AarDependenceInfo', "Found [${library.resolvedCoordinates}]'s manifest file: ${manifest}" def xmlManifest = new XmlParser().parse(manifest) return xmlManifest.@package } + File getLibManifestFile() { + if (Build.V3_3_OR_LATER) { + return getFile(library.manifest, 'library_manifest', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) + } else if (Build.V3_2_OR_LATER) { + return getFile(library.manifest, 'merged_manifests',library.projectVariant, + "process${library.projectVariant.capitalize()}Manifest","merged", + SdkConstants.ANDROID_MANIFEST_XML) + } else { + return getFile(library.manifest, 'manifests', 'full', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) + } + } + File getIntermediatesDir() { if (intermediatesFile == null) { String path = library.folder.path diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy index 065a8c1..976709f 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy @@ -1,7 +1,7 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant -import com.android.build.gradle.tasks.MergeManifests +import com.android.build.gradle.tasks.ManifestProcessorTask import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.DependenceInfo import com.didi.virtualapk.support.ScopeCompat @@ -24,7 +24,7 @@ import java.util.function.Predicate * * @author zhengtao */ -class MergeManifestsHooker extends GradleTaskHooker { +class MergeManifestsHooker extends GradleTaskHooker { public static final String ANDROID_NAMESPACE = 'http://schemas.android.com/apk/res/android' @@ -38,9 +38,9 @@ class MergeManifestsHooker extends GradleTaskHooker { } @Override - void beforeTaskExecute(MergeManifests task) { + void beforeTaskExecute(ManifestProcessorTask task) { - def stripAarNames = vaContext.stripDependencies. + Set stripAarNames = vaContext.stripDependencies. findAll { it.dependenceType == DependenceInfo.DependenceType.AAR }. @@ -57,9 +57,9 @@ class MergeManifestsHooker extends GradleTaskHooker { * Filter specific attributes from element after MergeManifests task executed */ @Override - void afterTaskExecute(MergeManifests task) { + void afterTaskExecute(ManifestProcessorTask task) { def MERGED_MANIFESTS = ScopeCompat.getArtifact(project, "MERGED_MANIFESTS") - if (Build.isSupportVersion(project,Build.VERSION_CODE.V3_1_X)) { + if (Build.V3_1_OR_LATER) { File outputFile = (Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') .call('from', MERGED_MANIFESTS, ScopeCompat.getArtifactFile(scope, project, MERGED_MANIFESTS)) .call('element', variantData.outputScope.mainSplit)) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy index 67fcbb3..3811a7e 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy @@ -1,22 +1,16 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant -import com.android.build.gradle.internal.ide.ArtifactDependencyGraph import com.android.build.gradle.internal.tasks.AppPreBuildTask import com.android.builder.model.Dependencies -import com.android.builder.model.SyncIssue -import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.AarDependenceInfo import com.didi.virtualapk.collector.dependence.DependenceInfo import com.didi.virtualapk.collector.dependence.JarDependenceInfo +import com.didi.virtualapk.support.ArtifactDependencyGraphCompat import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log -import com.didi.virtualapk.utils.Reflect -import com.google.common.collect.ImmutableMap import org.gradle.api.Project -import java.util.function.Consumer - /** * Gather list of dependencies(aar&jar) need to be stripped&retained after the PrepareDependenciesTask finished. * The entire stripped operation throughout the build lifecycle is based on the result of this hooker。 @@ -63,21 +57,8 @@ class PrepareDependenciesHooker extends GradleTaskHooker { */ @Override void afterTaskExecute(AppPreBuildTask task) { - Consumer consumer = new Consumer() { - @Override - void accept(SyncIssue syncIssue) { - Log.i 'PrepareDependenciesHooker', "Error: ${syncIssue}" - } - } - Dependencies dependencies - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { - ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') - .call('computeBuildMapping', project.gradle) - .get() - dependencies = new ArtifactDependencyGraph().createDependencies(scope, false, buildMapping, consumer) - } else { - dependencies = new ArtifactDependencyGraph().createDependencies(scope, false, consumer) - } + + Dependencies dependencies = ArtifactDependencyGraphCompat.createDependencies(project,scope) dependencies.libraries.each { def mavenCoordinates = it.resolvedCoordinates @@ -137,6 +118,7 @@ class PrepareDependenciesHooker extends GradleTaskHooker { mark() } + void checkDependencies() { ArrayList allRetainedDependencies = new ArrayList<>() allRetainedDependencies.addAll(retainedAarLibs) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy index d66a9e6..b365fa3 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy @@ -62,7 +62,7 @@ class ProcessResourcesHooker extends GradleTaskHooker { void afterTaskExecute(ProcessAndroidResources par) { def PROCESSED_RES = ScopeCompat.getArtifact(project, "PROCESSED_RES") - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + if (Build.V3_1_OR_LATER) { File outputFile = Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') .call('from', PROCESSED_RES, ScopeCompat.getArtifactFile(scope, project, PROCESSED_RES)) .call('element', variantData.outputScope.mainSplit) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy index f688058..5f760a5 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy @@ -1,44 +1,38 @@ package com.didi.virtualapk.os -import org.gradle.api.Project +import static com.android.builder.model.Version.ANDROID_GRADLE_PLUGIN_VERSION final class Build { - public static final String GRADLE_VERSION_SDK_INT = 'va.gradle.version.sdk_int' + /** + * Android Gradle Plugin 版本,3 位数,最后一位永远是 0,比如 3.0.0 对应 300,3.2.1 对应 320 + */ + public static final int AGP_VERSION = getAgpVersion() + + public static final Boolean V3_1_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_1_X + public static final Boolean V3_2_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_2_X + public static final Boolean V3_3_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_3_X + + /** + * 以 int 形式返回 android gradle plugin 版本,比如 300,310,320 + * @return + */ + private static int getAgpVersion() { + String[] versionArr = ANDROID_GRADLE_PLUGIN_VERSION.split("\\.") + return Integer.valueOf(versionArr[0]) * 100 + Integer.valueOf(versionArr[1]) * 10 + } static interface VERSION_CODE { int NONE = 0 int V3_1_X = 310 int V3_2_X = 320 + int V3_3_X = 330 + int V3_4_X = 340 + int V3_5_X = 350 } - static void initGradleVersion(Project project) { - if (findClass("com.android.build.gradle.internal.scope.InternalArtifactType")) { - project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_2_X) - return - } - - if (!findClass("com.android.builder.core.VariantConfiguration")) { - project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_1_X) - return - } - - project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.NONE) - } - - - private static findClass(String className) { - try { - Class.forName(className) - return true - } catch (Throwable ignored) { - return false - } - } - - - static boolean isSupportVersion(Project project, int minVersion) { - return project.extensions.extraProperties.get(GRADLE_VERSION_SDK_INT) >= minVersion + static boolean isSupportVersion(int minVersion) { + return AGP_VERSION >= minVersion } } diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy new file mode 100644 index 0000000..431982a --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy @@ -0,0 +1,83 @@ +package com.didi.virtualapk.support + +import com.android.build.gradle.internal.scope.VariantScope +import com.android.builder.model.Dependencies +import com.android.builder.model.SyncIssue +import com.didi.virtualapk.os.Build +import com.didi.virtualapk.utils.Log +import com.google.common.collect.ImmutableMap +import org.gradle.api.Project + +import java.util.function.Consumer + +import static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH +import static CompatUtil.loadClass + +/** + * @author 潘志会 @ Zhihu Inc. + * @since 2019/05/27 + */ +class ArtifactDependencyGraphCompat { + public static final String GRAPH_CLASS_NAME_3_3_X = "com.android.build.gradle.internal.ide.dependencies.ArtifactDependencyGraph" + public static final String GRAPH_NAME_PRE_3_3_X = "com.android.build.gradle.internal.ide.ArtifactDependencyGraph" + + public static final String BUILD_MAPPING_UTILS = "com.android.build.gradle.internal.ide.dependencies.BuildMappingUtils" + public static final String ARTIFACT_UTILS = "com.android.build.gradle.internal.ide.dependencies.ArtifactUtils" + public static final String CLASS_MODULE_BUILDER_3_1_X = "com.android.build.gradle.internal.ide.ModelBuilder" + + static Class getCompatClass() { + if (Build.V3_3_OR_LATER) { + return loadClass(GRAPH_CLASS_NAME_3_3_X) + } else { + return loadClass(GRAPH_NAME_PRE_3_3_X) + } + } + + static Set getAllArtifacts(Project project, applicationVariant) { + def scope = applicationVariant.variantData.scope + if (Build.V3_3_OR_LATER) { + // Set + // com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact,属于 AGP 的类 + loadClass(ARTIFACT_UTILS).getAllArtifacts(scope, COMPILE_CLASSPATH, null, getBuildMapping(project)) + } else if (Build.V3_1_OR_LATER) { + // Set + // HashableResolvedArtifactResult 为 ResolvedArtifactResult 的子类,后者属于 gradle 的类 + return getCompatClass().getAllArtifacts(scope, COMPILE_CLASSPATH, null, getBuildMapping(project)) + } else { + // 同 V3_1_X + return getCompatClass().getAllArtifacts(scope, COMPILE_CLASSPATH, null) + } + } + + static Dependencies createDependencies(Project project, VariantScope scope) { + Consumer consumer = new Consumer() { + @Override + void accept(SyncIssue syncIssue) { + Log.i 'PrepareDependenciesHooker', "Error: ${syncIssue}" + } + } + Dependencies dependencies + if (Build.V3_3_OR_LATER) { + dependencies = getCompatClass().newInstance() + .createDependencies(scope, false, getBuildMapping(project), consumer) + } else if (Build.V3_1_OR_LATER) { + dependencies = getCompatClass().newInstance() + .createDependencies(scope, false, getBuildMapping(project), consumer) + } else { + dependencies = getCompatClass().newInstance() + .createDependencies(scope, false, consumer) + } + return dependencies + } + + static ImmutableMap getBuildMapping(Project project) { + ImmutableMap buildMapping = null + if (Build.V3_3_OR_LATER) { + buildMapping = loadClass(BUILD_MAPPING_UTILS).computeBuildMapping(project.gradle) + } else if (Build.V3_1_OR_LATER) { + buildMapping = loadClass(CLASS_MODULE_BUILDER_3_1_X).computeBuildMapping(project.gradle) + } + return buildMapping; + } + +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy new file mode 100644 index 0000000..190fcad --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy @@ -0,0 +1,11 @@ +package com.didi.virtualapk.support; + +/** + * @author 潘志会 @ Zhihu Inc. + * @since 2019/05/27 + */ +class CompatUtil { + static Class loadClass(String className) { + return CompatUtil.class.classLoader.loadClass(className) + } +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy new file mode 100644 index 0000000..8fcc38e --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy @@ -0,0 +1,43 @@ +package com.didi.virtualapk.support + + +import com.didi.virtualapk.os.Build + +/** + * @author 潘志会 @ Zhihu Inc. + * @since 2019/05/27 + */ +class ResolvedArtifactCompat { + static getComponentIdentifier(artifact) { + def componentIdentifier = null + if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { + componentIdentifier = artifact.componentIdentifier + } else { + componentIdentifier = artifact.id.componentIdentifier + } + return componentIdentifier + } + + static getFile(artifact) { + File file = null + if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { + file = artifact.artifactFile + } else { + file = artifact.file + } + return file + } + + static getVariantName(artifact) { + // artifact 在 3.3 以上是 com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact + // artifact 在 3.3 以下是 org.gradle.api.artifacts.result.ResolvedArtifactResult + String variantName = null + if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { + variantName = artifact.variantName + } else { + variantName = CompatUtil.loadClass(ArtifactDependencyGraphCompat.GRAPH_NAME_PRE_3_3_X).getVariant(artifact) + + } + return variantName + } +} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy index 0aa594d..e085d66 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy @@ -9,7 +9,7 @@ final class ScopeCompat { def static getArtifact(Project project, String name) { - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { + if (Build.V3_2_OR_LATER) { return Reflect.on("com.android.build.gradle.internal.scope.InternalArtifactType") .field(name).get() } else { @@ -20,7 +20,7 @@ final class ScopeCompat { def static getArtifactFile(VariantScope scope, Project project, def artifact) { - if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { + if (Build.V3_2_OR_LATER) { return scope.artifacts.getFinalArtifactFiles(artifact) } else { return scope.getOutput(artifact) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy new file mode 100644 index 0000000..bba1bac --- /dev/null +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy @@ -0,0 +1,43 @@ +package com.didi.virtualapk.support + +import com.android.build.gradle.AppPlugin +import com.didi.virtualapk.os.Build +import com.didi.virtualapk.utils.Reflect +import org.gradle.api.Action +import org.gradle.api.Project + +/** + * @author 潘志会 @ Zhihu Inc. + * @since 2019/05/27 + */ +class TaskFactoryCompat { + static getTaskFactory(AppPlugin appPlugin, Project project) { + def taskFactory = null + if (Build.V3_1_OR_LATER) { + taskFactory = appPlugin.taskManager.taskFactory + } else { + taskFactory = Reflect.on('com.android.build.gradle.internal.TaskContainerAdaptor') + .create(project.tasks) + .get() + } + return taskFactory + } + + static add(taskFactory, String name, Class clazz, Action configAction) { + if (Build.V3_3_OR_LATER) { + taskFactory.register(name, clazz, configAction) + } else { + taskFactory.create(name, clazz, configAction) + } + } + + static configure(taskFactory, String name, Action action) { + if (Build.V3_1_OR_LATER) { + taskFactory.configure(name, action) + } else { + taskFactory.named(name, action) + } + } + + +} From 5a958458a8bf65e6ede5809b53619280480ad52b Mon Sep 17 00:00:00 2001 From: superq_sky Date: Fri, 28 Jun 2019 20:15:47 +0800 Subject: [PATCH 10/10] =?UTF-8?q?Revert=20"=E6=B7=BB=E5=8A=A0=E5=AF=B9=20A?= =?UTF-8?q?ndroid=20Gradle=20Plugin=203.3=20=E7=9A=84=E6=94=AF=E6=8C=81"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PluginDemo/app/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../com.didi.virtualapk/BasePlugin.groovy | 65 ++++++++++----- .../com.didi.virtualapk/VAHostPlugin.groovy | 43 +++++----- .../com.didi.virtualapk/VAPlugin.groovy | 8 +- .../dependence/AarDependenceInfo.groovy | 15 +--- .../hooker/MergeManifestsHooker.groovy | 12 +-- .../hooker/PrepareDependenciesHooker.groovy | 26 +++++- .../hooker/ProcessResourcesHooker.groovy | 2 +- .../com.didi.virtualapk/os/Build.groovy | 52 +++++++----- .../ArtifactDependencyGraphCompat.groovy | 83 ------------------- .../support/CompatUtil.groovy | 11 --- .../support/ResolvedArtifactCompat.groovy | 43 ---------- .../support/ScopeCompat.groovy | 4 +- .../support/TaskFactoryCompat.groovy | 43 ---------- 16 files changed, 134 insertions(+), 279 deletions(-) delete mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy delete mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy delete mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy delete mode 100644 virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy diff --git a/PluginDemo/app/build.gradle b/PluginDemo/app/build.gradle index 120e5c8..c7d16d6 100644 --- a/PluginDemo/app/build.gradle +++ b/PluginDemo/app/build.gradle @@ -54,7 +54,7 @@ dependencies { // the following aars are also compiled in host project, so they will be filterd when build plugin apk. // but, wo can still visit their Class and Resources. implementation 'com.android.support:appcompat-v7:23.4.0' - implementation 'com.didi.virtualapk:core:0.9.9.1-dev' + implementation 'com.didi.virtualapk:0.9.9.1-dev' } apply plugin: 'com.didi.virtualapk.plugin' diff --git a/PluginDemo/gradle/wrapper/gradle-wrapper.properties b/PluginDemo/gradle/wrapper/gradle-wrapper.properties index cb97588..c3510d6 100644 --- a/PluginDemo/gradle/wrapper/gradle-wrapper.properties +++ b/PluginDemo/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5c6313c..57a9bdc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy index 4666958..1b0336d 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/BasePlugin.groovy @@ -2,14 +2,15 @@ package com.didi.virtualapk import com.android.build.gradle.AppExtension import com.android.build.gradle.AppPlugin +import com.android.build.gradle.internal.TaskFactory +import com.android.build.gradle.internal.TaskManager import com.android.build.gradle.internal.api.ApplicationVariantImpl -import com.android.build.gradle.internal.scope.VariantScope import com.android.build.gradle.internal.variant.VariantFactory -import com.didi.virtualapk.support.TaskFactoryCompat +import com.android.builder.core.VariantType +import com.didi.virtualapk.os.Build import com.didi.virtualapk.tasks.AssemblePlugin import com.didi.virtualapk.utils.Log import com.didi.virtualapk.utils.Reflect -import groovy.transform.TypeChecked import org.gradle.api.Action import org.gradle.api.Plugin import org.gradle.api.Project @@ -31,7 +32,7 @@ public abstract class BasePlugin implements Plugin { protected Project project protected Instantiator instantiator - def taskFactory + protected TaskFactory taskFactory boolean checkVariantFactoryInvoked @@ -44,6 +45,8 @@ public abstract class BasePlugin implements Plugin { public void apply(Project project) { this.project = project + Build.initGradleVersion(project) + AppPlugin appPlugin = project.plugins.findPlugin(AppPlugin) Reflect reflect = Reflect.on(appPlugin.variantManager) @@ -68,7 +71,14 @@ public abstract class BasePlugin implements Plugin { project.extensions.create('virtualApk', VAExtention) - taskFactory = TaskFactoryCompat.getTaskFactory(appPlugin, project) + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + TaskManager taskManager = Reflect.on(appPlugin).field('taskManager').get() + taskFactory = taskManager.getTaskFactory() + } else { + taskFactory = Reflect.on('com.android.build.gradle.internal.TaskContainerAdaptor') + .create(project.tasks) + .get() + } project.afterEvaluate { if (!checkVariantFactoryInvoked) { @@ -81,7 +91,7 @@ public abstract class BasePlugin implements Plugin { def final variantPluginTaskName = createPluginTaskName(variantAssembleTaskName) final def configAction = new AssemblePlugin.ConfigAction(project, variant) - TaskFactoryCompat.add(taskFactory, variantPluginTaskName, AssemblePlugin, configAction) + taskFactory.create(variantPluginTaskName, AssemblePlugin, configAction) Action action = new Action() { @Override @@ -90,7 +100,11 @@ public abstract class BasePlugin implements Plugin { } } - TaskFactoryCompat.configure(taskFactory, "assemblePlugin", action) + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + taskFactory.configure("assemblePlugin", action) + } else { + taskFactory.named("assemblePlugin", action) + } } } } @@ -105,19 +119,35 @@ public abstract class BasePlugin implements Plugin { return name.replace('Release', '') } - /** - * 通过启动命令判断是否要运行的是是打插件包的 Task - */ private boolean evaluateBuildingPlugin(AppPlugin appPlugin, Project project) { def startParameter = project.gradle.startParameter def targetTasks = startParameter.taskNames def pluginTasks = ['assemblePlugin'] as List - if (!appPlugin.variantManager.productFlavors.isEmpty()) { - appPlugin.variantManager.variantScopes - .findAll { it.variantConfiguration.buildType.name == "release" } - .forEach { VariantScope scope -> addTaskToListForScope(scope, pluginTasks) } + appPlugin.variantManager.buildTypes.each { + def buildType = it.value.buildType + if ('release' != buildType.name) { + return + } + if (appPlugin.variantManager.productFlavors.isEmpty()) { + return + } + + appPlugin.variantManager.productFlavors.each { + String variantName + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + variantName = Reflect.on('com.android.build.gradle.internal.core.VariantConfiguration') + .call('computeFullName', it.key, buildType, VariantType.DEFAULT, null) + .get() + } else { + variantName = Reflect.on('com.android.builder.core.VariantConfiguration') + .call('computeFullName', it.key, buildType, VariantType.DEFAULT, null) + .get() + } + def variantPluginTaskName = createPluginTaskName("assemble${variantName.capitalize()}Plugin".toString()) + pluginTasks.add(variantPluginTaskName) + } } // pluginTasks.each { @@ -141,13 +171,6 @@ public abstract class BasePlugin implements Plugin { return isBuildingPlugin } - @TypeChecked - private void addTaskToListForScope(VariantScope scope, List pluginTasks) { - String variantName = scope.fullVariantName - def variantPluginTaskName = createPluginTaskName("assemble${variantName.capitalize()}Plugin".toString()) - pluginTasks.add(variantPluginTaskName) - } - protected abstract void beforeCreateAndroidTasks(boolean isBuildingPlugin) protected final VAExtention getVirtualApk() { diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy index 945a330..ac4a53e 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAHostPlugin.groovy @@ -1,16 +1,17 @@ package com.didi.virtualapk - import com.android.build.gradle.api.ApplicationVariant import com.android.build.gradle.internal.api.ApplicationVariantImpl +import com.android.build.gradle.internal.ide.ArtifactDependencyGraph import com.android.build.gradle.internal.pipeline.TransformTask +import com.android.build.gradle.internal.publishing.AndroidArtifacts import com.android.build.gradle.internal.transforms.ProGuardTransform import com.android.build.gradle.tasks.ProcessAndroidResources -import com.didi.virtualapk.support.ArtifactDependencyGraphCompat -import com.didi.virtualapk.support.ResolvedArtifactCompat import com.didi.virtualapk.os.Build import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log +import com.didi.virtualapk.utils.Reflect +import com.google.common.collect.ImmutableMap import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.component.ComponentIdentifier @@ -35,14 +36,14 @@ public class VAHostPlugin implements Plugin { this.project = project + Build.initGradleVersion(project) + //The target project must be a android application module if (!project.plugins.hasPlugin('com.android.application')) { Log.e(TAG, "application required!") return } - Log.i(TAG, "android gradle plugin version is " + Build.AGP_VERSION) - vaHostDir = new File(project.getBuildDir(), "VAHost") project.afterEvaluate { @@ -90,20 +91,28 @@ public class VAHostPlugin implements Plugin { FileUtil.saveFile(vaHostDir, "versions", { List deps = new ArrayList() Log.i TAG, "Used compileClasspath: ${applicationVariant.name}" - Set compileArtifacts = ArtifactDependencyGraphCompat.getAllArtifacts(project, applicationVariant) + Set compileArtifacts + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') + .call('computeBuildMapping', project.gradle) + .get() + compileArtifacts = ArtifactDependencyGraph.getAllArtifacts( + applicationVariant.variantData.scope, AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, null, buildMapping) + } else { + compileArtifacts = ArtifactDependencyGraph.getAllArtifacts( + applicationVariant.variantData.scope, AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH, null) + } - compileArtifacts.each { artifact -> - // artifact 在 3.3 以上是 com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact - // artifact 在 3.3 以下是 org.gradle.api.artifacts.result.ResolvedArtifactResult - ComponentIdentifier id = ResolvedArtifactCompat.getComponentIdentifier(artifact) + compileArtifacts.each { ArtifactDependencyGraph.HashableResolvedArtifactResult artifact -> + ComponentIdentifier id = artifact.id.componentIdentifier if (id instanceof ProjectComponentIdentifier) { - deps.add("${id.projectPath.replace(':', '')}" + - ":${ResolvedArtifactCompat.getVariantName(artifact)}" + - ":unspecified ${getArtifactFileLength(artifact)}") + deps.add("${id.projectPath.replace(':', '')}:${ArtifactDependencyGraph.getVariant(artifact)}:unspecified ${artifact.file.length()}") + } else if (id instanceof ModuleComponentIdentifier) { - deps.add("${id.group}:${id.module}:${id.version} ${getArtifactFileLength(artifact)}") + deps.add("${id.group}:${id.module}:${id.version} ${artifact.file.length()}") + } else { -// deps.add("${id.displayName.replace(':', '')}:unspecified:unspecified ${getArtifactFileLength(artifact)}") + deps.add("${artifact.id.displayName.replace(':', '')}:unspecified:unspecified ${artifact.file.length()}") } } @@ -114,10 +123,6 @@ public class VAHostPlugin implements Plugin { } - private long getArtifactFileLength(artifact){ - return ResolvedArtifactCompat.getFile(artifact).length() - } - /** * Save R symbol file */ diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy index c6661bf..93fd8e5 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/VAPlugin.groovy @@ -5,7 +5,6 @@ import com.android.build.gradle.internal.api.ApplicationVariantImpl import com.android.build.gradle.options.BooleanOption import com.android.build.gradle.options.ProjectOptions import com.didi.virtualapk.hooker.* -import com.didi.virtualapk.os.Build import com.didi.virtualapk.transform.StripClassAndResTransform import com.didi.virtualapk.utils.FileBinaryCategory import com.didi.virtualapk.utils.Log @@ -228,11 +227,8 @@ class VAPlugin extends BasePlugin { AppPlugin appPlugin = project.plugins.findPlugin(AppPlugin) ProjectOptions projectOptions = Reflect.on(appPlugin).field('projectOptions').get() - // 330 此处已经无效了,永远为 true - if (!Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)){ - if (projectOptions.get(BooleanOption.ENABLE_DEX_ARCHIVE)) { - throw new InvalidUserDataException("Can't using incremental dexing mode, please add 'android.useDexArchive=false' in gradle.properties of :${project.name}.") - } + if (projectOptions.get(BooleanOption.ENABLE_DEX_ARCHIVE)) { + throw new InvalidUserDataException("Can't using incremental dexing mode, please add 'android.useDexArchive=false' in gradle.properties of :${project.name}.") } // project.ext.set('android.useDexArchive', false) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy index b501e91..94ab3f3 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/collector/dependence/AarDependenceInfo.groovy @@ -6,7 +6,6 @@ import com.android.builder.model.AndroidLibrary import com.android.utils.FileUtils import com.didi.virtualapk.collector.res.ResourceEntry import com.didi.virtualapk.collector.res.StyleableEntry -import com.didi.virtualapk.os.Build import com.didi.virtualapk.utils.Log import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap @@ -99,24 +98,12 @@ class AarDependenceInfo extends DependenceInfo { * @return package name of this library */ public String getPackage() { - File manifest = getLibManifestFile() + File manifest = getFile(library.manifest, 'manifests', 'full', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) Log.i 'AarDependenceInfo', "Found [${library.resolvedCoordinates}]'s manifest file: ${manifest}" def xmlManifest = new XmlParser().parse(manifest) return xmlManifest.@package } - File getLibManifestFile() { - if (Build.V3_3_OR_LATER) { - return getFile(library.manifest, 'library_manifest', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) - } else if (Build.V3_2_OR_LATER) { - return getFile(library.manifest, 'merged_manifests',library.projectVariant, - "process${library.projectVariant.capitalize()}Manifest","merged", - SdkConstants.ANDROID_MANIFEST_XML) - } else { - return getFile(library.manifest, 'manifests', 'full', library.projectVariant, SdkConstants.ANDROID_MANIFEST_XML) - } - } - File getIntermediatesDir() { if (intermediatesFile == null) { String path = library.folder.path diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy index 976709f..065a8c1 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/MergeManifestsHooker.groovy @@ -1,7 +1,7 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant -import com.android.build.gradle.tasks.ManifestProcessorTask +import com.android.build.gradle.tasks.MergeManifests import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.DependenceInfo import com.didi.virtualapk.support.ScopeCompat @@ -24,7 +24,7 @@ import java.util.function.Predicate * * @author zhengtao */ -class MergeManifestsHooker extends GradleTaskHooker { +class MergeManifestsHooker extends GradleTaskHooker { public static final String ANDROID_NAMESPACE = 'http://schemas.android.com/apk/res/android' @@ -38,9 +38,9 @@ class MergeManifestsHooker extends GradleTaskHooker { } @Override - void beforeTaskExecute(ManifestProcessorTask task) { + void beforeTaskExecute(MergeManifests task) { - Set stripAarNames = vaContext.stripDependencies. + def stripAarNames = vaContext.stripDependencies. findAll { it.dependenceType == DependenceInfo.DependenceType.AAR }. @@ -57,9 +57,9 @@ class MergeManifestsHooker extends GradleTaskHooker { * Filter specific attributes from element after MergeManifests task executed */ @Override - void afterTaskExecute(ManifestProcessorTask task) { + void afterTaskExecute(MergeManifests task) { def MERGED_MANIFESTS = ScopeCompat.getArtifact(project, "MERGED_MANIFESTS") - if (Build.V3_1_OR_LATER) { + if (Build.isSupportVersion(project,Build.VERSION_CODE.V3_1_X)) { File outputFile = (Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') .call('from', MERGED_MANIFESTS, ScopeCompat.getArtifactFile(scope, project, MERGED_MANIFESTS)) .call('element', variantData.outputScope.mainSplit)) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy index 3811a7e..67fcbb3 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/PrepareDependenciesHooker.groovy @@ -1,16 +1,22 @@ package com.didi.virtualapk.hooker import com.android.build.gradle.api.ApkVariant +import com.android.build.gradle.internal.ide.ArtifactDependencyGraph import com.android.build.gradle.internal.tasks.AppPreBuildTask import com.android.builder.model.Dependencies +import com.android.builder.model.SyncIssue +import com.didi.virtualapk.os.Build import com.didi.virtualapk.collector.dependence.AarDependenceInfo import com.didi.virtualapk.collector.dependence.DependenceInfo import com.didi.virtualapk.collector.dependence.JarDependenceInfo -import com.didi.virtualapk.support.ArtifactDependencyGraphCompat import com.didi.virtualapk.utils.FileUtil import com.didi.virtualapk.utils.Log +import com.didi.virtualapk.utils.Reflect +import com.google.common.collect.ImmutableMap import org.gradle.api.Project +import java.util.function.Consumer + /** * Gather list of dependencies(aar&jar) need to be stripped&retained after the PrepareDependenciesTask finished. * The entire stripped operation throughout the build lifecycle is based on the result of this hooker。 @@ -57,8 +63,21 @@ class PrepareDependenciesHooker extends GradleTaskHooker { */ @Override void afterTaskExecute(AppPreBuildTask task) { - - Dependencies dependencies = ArtifactDependencyGraphCompat.createDependencies(project,scope) + Consumer consumer = new Consumer() { + @Override + void accept(SyncIssue syncIssue) { + Log.i 'PrepareDependenciesHooker', "Error: ${syncIssue}" + } + } + Dependencies dependencies + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { + ImmutableMap buildMapping = Reflect.on('com.android.build.gradle.internal.ide.ModelBuilder') + .call('computeBuildMapping', project.gradle) + .get() + dependencies = new ArtifactDependencyGraph().createDependencies(scope, false, buildMapping, consumer) + } else { + dependencies = new ArtifactDependencyGraph().createDependencies(scope, false, consumer) + } dependencies.libraries.each { def mavenCoordinates = it.resolvedCoordinates @@ -118,7 +137,6 @@ class PrepareDependenciesHooker extends GradleTaskHooker { mark() } - void checkDependencies() { ArrayList allRetainedDependencies = new ArrayList<>() allRetainedDependencies.addAll(retainedAarLibs) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy index b365fa3..d66a9e6 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/hooker/ProcessResourcesHooker.groovy @@ -62,7 +62,7 @@ class ProcessResourcesHooker extends GradleTaskHooker { void afterTaskExecute(ProcessAndroidResources par) { def PROCESSED_RES = ScopeCompat.getArtifact(project, "PROCESSED_RES") - if (Build.V3_1_OR_LATER) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_1_X)) { File outputFile = Reflect.on('com.android.build.gradle.internal.scope.ExistingBuildElements') .call('from', PROCESSED_RES, ScopeCompat.getArtifactFile(scope, project, PROCESSED_RES)) .call('element', variantData.outputScope.mainSplit) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy index 5f760a5..f688058 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/os/Build.groovy @@ -1,38 +1,44 @@ package com.didi.virtualapk.os -import static com.android.builder.model.Version.ANDROID_GRADLE_PLUGIN_VERSION +import org.gradle.api.Project final class Build { - /** - * Android Gradle Plugin 版本,3 位数,最后一位永远是 0,比如 3.0.0 对应 300,3.2.1 对应 320 - */ - public static final int AGP_VERSION = getAgpVersion() - - public static final Boolean V3_1_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_1_X - public static final Boolean V3_2_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_2_X - public static final Boolean V3_3_OR_LATER = AGP_VERSION >= VERSION_CODE.V3_3_X - - /** - * 以 int 形式返回 android gradle plugin 版本,比如 300,310,320 - * @return - */ - private static int getAgpVersion() { - String[] versionArr = ANDROID_GRADLE_PLUGIN_VERSION.split("\\.") - return Integer.valueOf(versionArr[0]) * 100 + Integer.valueOf(versionArr[1]) * 10 - } + public static final String GRADLE_VERSION_SDK_INT = 'va.gradle.version.sdk_int' static interface VERSION_CODE { int NONE = 0 int V3_1_X = 310 int V3_2_X = 320 - int V3_3_X = 330 - int V3_4_X = 340 - int V3_5_X = 350 } - static boolean isSupportVersion(int minVersion) { - return AGP_VERSION >= minVersion + static void initGradleVersion(Project project) { + if (findClass("com.android.build.gradle.internal.scope.InternalArtifactType")) { + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_2_X) + return + } + + if (!findClass("com.android.builder.core.VariantConfiguration")) { + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.V3_1_X) + return + } + + project.ext.set(GRADLE_VERSION_SDK_INT, VERSION_CODE.NONE) + } + + + private static findClass(String className) { + try { + Class.forName(className) + return true + } catch (Throwable ignored) { + return false + } + } + + + static boolean isSupportVersion(Project project, int minVersion) { + return project.extensions.extraProperties.get(GRADLE_VERSION_SDK_INT) >= minVersion } } diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy deleted file mode 100644 index 431982a..0000000 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ArtifactDependencyGraphCompat.groovy +++ /dev/null @@ -1,83 +0,0 @@ -package com.didi.virtualapk.support - -import com.android.build.gradle.internal.scope.VariantScope -import com.android.builder.model.Dependencies -import com.android.builder.model.SyncIssue -import com.didi.virtualapk.os.Build -import com.didi.virtualapk.utils.Log -import com.google.common.collect.ImmutableMap -import org.gradle.api.Project - -import java.util.function.Consumer - -import static com.android.build.gradle.internal.publishing.AndroidArtifacts.ConsumedConfigType.COMPILE_CLASSPATH -import static CompatUtil.loadClass - -/** - * @author 潘志会 @ Zhihu Inc. - * @since 2019/05/27 - */ -class ArtifactDependencyGraphCompat { - public static final String GRAPH_CLASS_NAME_3_3_X = "com.android.build.gradle.internal.ide.dependencies.ArtifactDependencyGraph" - public static final String GRAPH_NAME_PRE_3_3_X = "com.android.build.gradle.internal.ide.ArtifactDependencyGraph" - - public static final String BUILD_MAPPING_UTILS = "com.android.build.gradle.internal.ide.dependencies.BuildMappingUtils" - public static final String ARTIFACT_UTILS = "com.android.build.gradle.internal.ide.dependencies.ArtifactUtils" - public static final String CLASS_MODULE_BUILDER_3_1_X = "com.android.build.gradle.internal.ide.ModelBuilder" - - static Class getCompatClass() { - if (Build.V3_3_OR_LATER) { - return loadClass(GRAPH_CLASS_NAME_3_3_X) - } else { - return loadClass(GRAPH_NAME_PRE_3_3_X) - } - } - - static Set getAllArtifacts(Project project, applicationVariant) { - def scope = applicationVariant.variantData.scope - if (Build.V3_3_OR_LATER) { - // Set - // com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact,属于 AGP 的类 - loadClass(ARTIFACT_UTILS).getAllArtifacts(scope, COMPILE_CLASSPATH, null, getBuildMapping(project)) - } else if (Build.V3_1_OR_LATER) { - // Set - // HashableResolvedArtifactResult 为 ResolvedArtifactResult 的子类,后者属于 gradle 的类 - return getCompatClass().getAllArtifacts(scope, COMPILE_CLASSPATH, null, getBuildMapping(project)) - } else { - // 同 V3_1_X - return getCompatClass().getAllArtifacts(scope, COMPILE_CLASSPATH, null) - } - } - - static Dependencies createDependencies(Project project, VariantScope scope) { - Consumer consumer = new Consumer() { - @Override - void accept(SyncIssue syncIssue) { - Log.i 'PrepareDependenciesHooker', "Error: ${syncIssue}" - } - } - Dependencies dependencies - if (Build.V3_3_OR_LATER) { - dependencies = getCompatClass().newInstance() - .createDependencies(scope, false, getBuildMapping(project), consumer) - } else if (Build.V3_1_OR_LATER) { - dependencies = getCompatClass().newInstance() - .createDependencies(scope, false, getBuildMapping(project), consumer) - } else { - dependencies = getCompatClass().newInstance() - .createDependencies(scope, false, consumer) - } - return dependencies - } - - static ImmutableMap getBuildMapping(Project project) { - ImmutableMap buildMapping = null - if (Build.V3_3_OR_LATER) { - buildMapping = loadClass(BUILD_MAPPING_UTILS).computeBuildMapping(project.gradle) - } else if (Build.V3_1_OR_LATER) { - buildMapping = loadClass(CLASS_MODULE_BUILDER_3_1_X).computeBuildMapping(project.gradle) - } - return buildMapping; - } - -} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy deleted file mode 100644 index 190fcad..0000000 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/CompatUtil.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package com.didi.virtualapk.support; - -/** - * @author 潘志会 @ Zhihu Inc. - * @since 2019/05/27 - */ -class CompatUtil { - static Class loadClass(String className) { - return CompatUtil.class.classLoader.loadClass(className) - } -} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy deleted file mode 100644 index 8fcc38e..0000000 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ResolvedArtifactCompat.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package com.didi.virtualapk.support - - -import com.didi.virtualapk.os.Build - -/** - * @author 潘志会 @ Zhihu Inc. - * @since 2019/05/27 - */ -class ResolvedArtifactCompat { - static getComponentIdentifier(artifact) { - def componentIdentifier = null - if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { - componentIdentifier = artifact.componentIdentifier - } else { - componentIdentifier = artifact.id.componentIdentifier - } - return componentIdentifier - } - - static getFile(artifact) { - File file = null - if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { - file = artifact.artifactFile - } else { - file = artifact.file - } - return file - } - - static getVariantName(artifact) { - // artifact 在 3.3 以上是 com.android.build.gradle.internal.ide.dependencies.ResolvedArtifact - // artifact 在 3.3 以下是 org.gradle.api.artifacts.result.ResolvedArtifactResult - String variantName = null - if (Build.isSupportVersion(Build.VERSION_CODE.V3_3_X)) { - variantName = artifact.variantName - } else { - variantName = CompatUtil.loadClass(ArtifactDependencyGraphCompat.GRAPH_NAME_PRE_3_3_X).getVariant(artifact) - - } - return variantName - } -} diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy index e085d66..0aa594d 100644 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy +++ b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/ScopeCompat.groovy @@ -9,7 +9,7 @@ final class ScopeCompat { def static getArtifact(Project project, String name) { - if (Build.V3_2_OR_LATER) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { return Reflect.on("com.android.build.gradle.internal.scope.InternalArtifactType") .field(name).get() } else { @@ -20,7 +20,7 @@ final class ScopeCompat { def static getArtifactFile(VariantScope scope, Project project, def artifact) { - if (Build.V3_2_OR_LATER) { + if (Build.isSupportVersion(project, Build.VERSION_CODE.V3_2_X)) { return scope.artifacts.getFinalArtifactFiles(artifact) } else { return scope.getOutput(artifact) diff --git a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy b/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy deleted file mode 100644 index bba1bac..0000000 --- a/virtualapk-gradle-plugin/src/main/groovy/com.didi.virtualapk/support/TaskFactoryCompat.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package com.didi.virtualapk.support - -import com.android.build.gradle.AppPlugin -import com.didi.virtualapk.os.Build -import com.didi.virtualapk.utils.Reflect -import org.gradle.api.Action -import org.gradle.api.Project - -/** - * @author 潘志会 @ Zhihu Inc. - * @since 2019/05/27 - */ -class TaskFactoryCompat { - static getTaskFactory(AppPlugin appPlugin, Project project) { - def taskFactory = null - if (Build.V3_1_OR_LATER) { - taskFactory = appPlugin.taskManager.taskFactory - } else { - taskFactory = Reflect.on('com.android.build.gradle.internal.TaskContainerAdaptor') - .create(project.tasks) - .get() - } - return taskFactory - } - - static add(taskFactory, String name, Class clazz, Action configAction) { - if (Build.V3_3_OR_LATER) { - taskFactory.register(name, clazz, configAction) - } else { - taskFactory.create(name, clazz, configAction) - } - } - - static configure(taskFactory, String name, Action action) { - if (Build.V3_1_OR_LATER) { - taskFactory.configure(name, action) - } else { - taskFactory.named(name, action) - } - } - - -}