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..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 @@ -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.CATEGORY_PREFIX)) { + return true; + } + } + + return false; } public static int getTheme(Context context, Intent intent) { diff --git a/CoreLibrary/upload.gradle b/CoreLibrary/upload.gradle index f8cbcd7..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.7.1" +version = "0.9.9.1-dev" install { 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/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/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 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 69c33d6..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.1-dev +VERSION=0.9.8.6.2-dev 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..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 @@ -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)) @@ -211,7 +206,7 @@ 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) } } @@ -244,9 +239,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 +275,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 +297,7 @@ public class VAHostPlugin implements Plugin { } } else { - if (type != 'attr'){ + if (type != 'attr') { println ">>>> ${type} : ${values[2]} is deleted" } @@ -328,7 +323,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/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") 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 } 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) + } + } + +}