diff --git a/README.md b/README.md
index 99f98e71..19678f5e 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,14 @@
[](https://github.com/kezong/fat-aar-android/blob/master/LICENSE)
[](https://maven-badges.herokuapp.com/maven-central/com.github.kezong/fat-aar)
-- [中文文档](./README_CN.md)
+This fork adds support for AGP 8.0
>**I am no longer engaged in research and development, so the project will not be updated and maintained.
**
>**You can try to use the following steps to reference the remote plugin. If it doesn't work on the new version of gradle, you can fork or download this project to modify it, the code of this project is not very complex.**
>
>**P.S. Hope Google can support this damn feature as soon as possible.**
-The solution of merging aar works with [AGP][3] `3.0` and higher. (Tested in AGP 3.0 - 7.1.0, and Gradle 4.9 - 7.3)
+The solution of merging aar works with [AGP][3] `3.0` and higher. (Tested in AGP 3.0 - 8.0.0, and Gradle 4.9 - 8.0)
## Getting Started
### Step 1: Add classpath
diff --git a/source/build.gradle b/source/build.gradle
index 913630b5..a6957adf 100644
--- a/source/build.gradle
+++ b/source/build.gradle
@@ -18,5 +18,7 @@ dependencies {
implementation gradleApi()
implementation localGroovy()
implementation "org.javassist:javassist:3.27.0-GA"
- implementation 'com.android.tools.build:gradle:4.2.0'
+ implementation 'com.android.tools.build:gradle:7.2.0'
+ implementation 'com.android.tools:common:30.2.0'
+ implementation 'org.ow2.asm:asm-commons:9.2'
}
diff --git a/source/gradle/wrapper/gradle-wrapper.properties b/source/gradle/wrapper/gradle-wrapper.properties
index 69a3256f..5b6171c9 100644
--- a/source/gradle/wrapper/gradle-wrapper.properties
+++ b/source/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-6.7.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
diff --git a/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy b/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy
index 97a49a43..22172f1e 100644
--- a/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy
+++ b/source/src/main/groovy/com/kezong/fataar/FatAarPlugin.groovy
@@ -7,6 +7,7 @@ import org.gradle.api.ProjectConfigurationException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency
+import org.gradle.api.provider.MapProperty
/**
* plugin entry
@@ -27,6 +28,8 @@ class FatAarPlugin implements Plugin {
private final Collection embedConfigurations = new ArrayList<>()
+ private MapProperty> variantPackagesProperty;
+
@Override
void apply(Project project) {
this.project = project
@@ -42,9 +45,14 @@ class FatAarPlugin implements Plugin {
}
private registerTransform() {
- transform = new RClassesTransform(project)
- // register in project.afterEvaluate is invalid.
- project.android.registerTransform(transform)
+ variantPackagesProperty = project.objects.mapProperty(String.class, List.class)
+ if (FatUtils.compareVersion(VersionAdapter.AGPVersion, "8.0.0") >= 0) {
+ FatAarPluginHelper.registerAsmTransformation(project, variantPackagesProperty)
+ } else {
+ transform = new RClassesTransform(project)
+ // register in project.afterEvaluate is invalid.
+ project.android.registerTransform(transform)
+ }
}
private void doAfterEvaluate() {
@@ -70,7 +78,7 @@ class FatAarPlugin implements Plugin {
}
if (!artifacts.isEmpty()) {
- def processor = new VariantProcessor(project, variant)
+ def processor = new VariantProcessor(project, variant, variantPackagesProperty)
processor.processVariant(artifacts, firstLevelDependencies, transform)
}
}
diff --git a/source/src/main/groovy/com/kezong/fataar/FatUtils.groovy b/source/src/main/groovy/com/kezong/fataar/FatUtils.groovy
index fb8dbea6..1b8f756b 100644
--- a/source/src/main/groovy/com/kezong/fataar/FatUtils.groovy
+++ b/source/src/main/groovy/com/kezong/fataar/FatUtils.groovy
@@ -107,6 +107,13 @@ class FatUtils {
}
}
+ /**
+ * @return true if current AGP version is at least "8.0.0" and false otherwise
+ */
+ static Boolean isAGPVersion8AndAbove(){
+ compareVersion(VersionAdapter.AGPVersion, "8.0.0") >= 0
+ }
+
static String formatDataSize(long size) {
String result
if (size < 1024) {
@@ -144,4 +151,4 @@ class FatUtils {
output.append("\n${file.getText("UTF-8")}\n")
}
}
-}
\ No newline at end of file
+}
diff --git a/source/src/main/groovy/com/kezong/fataar/FlavorArtifact.groovy b/source/src/main/groovy/com/kezong/fataar/FlavorArtifact.groovy
index 50945c79..6cead330 100755
--- a/source/src/main/groovy/com/kezong/fataar/FlavorArtifact.groovy
+++ b/source/src/main/groovy/com/kezong/fataar/FlavorArtifact.groovy
@@ -58,8 +58,7 @@ class FlavorArtifact {
} else { // try included builds
ResolvedDependencyResult resolvedResult = configuration.incoming.resolutionResult.allDependencies.find { result ->
if (result instanceof ResolvedDependencyResult && result.selected.selectionReason.compositeSubstitution) {
- return result.requested.group == unResolvedArtifact.moduleGroup
- && result.requested.module == unResolvedArtifact.moduleName
+ return result.requested.group == unResolvedArtifact.moduleGroup && result.requested.module == unResolvedArtifact.moduleName
}
return false
}
diff --git a/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy b/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy
index 7b275f49..626f4304 100755
--- a/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy
+++ b/source/src/main/groovy/com/kezong/fataar/VariantProcessor.groovy
@@ -1,7 +1,6 @@
package com.kezong.fataar
import com.android.build.gradle.api.LibraryVariant
-import com.android.build.gradle.internal.api.DefaultAndroidSourceSet
import com.android.build.gradle.tasks.ManifestProcessorTask
import org.gradle.api.Project
import org.gradle.api.Task
@@ -9,6 +8,8 @@ import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency
import org.gradle.api.internal.artifacts.ResolvableDependency
import org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.MapProperty
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskDependency
@@ -31,6 +32,8 @@ class VariantProcessor {
private Collection mAndroidArchiveLibraries = new ArrayList<>()
+ private ListProperty mAndroidArchiveLibrariesProperty
+
private Collection mJarFiles = new ArrayList<>()
private Collection mExplodeTasks = new ArrayList<>()
@@ -39,14 +42,17 @@ class VariantProcessor {
private TaskProvider mMergeClassTask
- VariantProcessor(Project project, LibraryVariant variant) {
+ VariantProcessor(Project project, LibraryVariant variant, MapProperty> variantPackagesProperty) {
mProject = project
mVariant = variant
mVersionAdapter = new VersionAdapter(project, variant)
+ mAndroidArchiveLibrariesProperty = mProject.objects.listProperty(AndroidArchiveLibrary.class)
+ variantPackagesProperty.put(mVariant.getName(), mAndroidArchiveLibrariesProperty)
}
void addAndroidArchiveLibrary(AndroidArchiveLibrary library) {
mAndroidArchiveLibraries.add(library)
+ mAndroidArchiveLibrariesProperty.add(library)
}
void addJarFile(File jar) {
@@ -179,11 +185,11 @@ class VariantProcessor {
private void processRClasses(RClassesTransform transform, TaskProvider bundleTask) {
TaskProvider reBundleTask = configureReBundleAarTask(bundleTask)
- TaskProvider transformTask = mProject.tasks.named("transformClassesWith${transform.name.capitalize()}For${mVariant.name.capitalize()}")
- transformTask.configure {
- it.dependsOn(mMergeClassTask)
- }
- if (mProject.fataar.transformR) {
+ if (mProject.fataar.transformR && !FatUtils.isAGPVersion8AndAbove()) {
+ TaskProvider transformTask = mProject.tasks.named("transformClassesWith${transform.name.capitalize()}For${mVariant.name.capitalize()}")
+ transformTask.configure {
+ it.dependsOn(mMergeClassTask)
+ }
transformRClasses(transform, transformTask, bundleTask, reBundleTask)
} else {
generateRClasses(bundleTask, reBundleTask)
@@ -351,6 +357,9 @@ class VariantProcessor {
private TaskProvider handleClassesMergeTask(final boolean isMinifyEnabled) {
final TaskProvider task = mProject.tasks.register("mergeClasses" + mVariant.name.capitalize()) {
+
+ outputs.upToDateWhen { false }
+
dependsOn(mExplodeTasks)
dependsOn(mVersionAdapter.getJavaCompileTask())
try {
@@ -444,6 +453,12 @@ class VariantProcessor {
.withPathSensitivity(PathSensitivity.RELATIVE)
inputs.files(mJarFiles).withPathSensitivity(PathSensitivity.RELATIVE)
}
+ // Asm tasks enabled from AGP 8 version
+ if(FatUtils.isAGPVersion8AndAbove()){
+ mProject.tasks.named("transform${mVariant.name.capitalize()}ClassesWithAsm").configure {
+ dependsOn(mMergeClassTask)
+ }
+ }
extractAnnotationsTask.configure {
mustRunAfter(mMergeClassTask)
}
diff --git a/source/src/main/java/com/kezong/fataar/FatAarPluginHelper.java b/source/src/main/java/com/kezong/fataar/FatAarPluginHelper.java
new file mode 100644
index 00000000..8c3db4e2
--- /dev/null
+++ b/source/src/main/java/com/kezong/fataar/FatAarPluginHelper.java
@@ -0,0 +1,110 @@
+package com.kezong.fataar;
+
+import com.android.build.api.instrumentation.AsmClassVisitorFactory;
+import com.android.build.api.instrumentation.ClassContext;
+import com.android.build.api.instrumentation.ClassData;
+import com.android.build.api.instrumentation.InstrumentationParameters;
+import com.android.build.api.instrumentation.InstrumentationScope;
+import com.android.build.api.variant.AndroidComponentsExtension;
+import com.android.build.api.variant.Variant;
+
+import org.gradle.api.Project;
+import org.gradle.api.provider.ListProperty;
+import org.gradle.api.provider.MapProperty;
+import org.gradle.api.provider.Property;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Optional;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import kotlin.Unit;
+import kotlin.text.StringsKt;
+
+import static com.android.build.api.instrumentation.FramesComputationMode.COPY_FRAMES;
+
+public class FatAarPluginHelper {
+
+ public static void registerAsmTransformation(
+ Project project,
+ MapProperty> variantPackagesProperty) {
+ AndroidComponentsExtension, ?, Variant> components =
+ project.getExtensions().getByType(AndroidComponentsExtension.class);
+ components.onVariants(components.selector().all(), variant -> {
+ variant.getInstrumentation().transformClassesWith(
+ RClassAsmTransformerFactory.class,
+ InstrumentationScope.PROJECT,
+ params -> {
+ params.getNamespace().set(variant.getNamespace());
+ params.getLibraryNamespaces().set(variantPackagesProperty.getting(variant.getName())
+ .map(list -> list.stream().map(it -> it.getPackageName()).collect(Collectors.toList()))
+ );
+ return Unit.INSTANCE;
+ });
+ variant.getInstrumentation().setAsmFramesComputationMode(COPY_FRAMES);
+ });
+ }
+
+ public abstract static class RClassAsmTransformerFactory implements AsmClassVisitorFactory {
+
+ public interface Params extends InstrumentationParameters {
+
+ @Input
+ Property getNamespace();
+
+ @Input
+ @Optional
+ ListProperty getLibraryNamespaces();
+ }
+
+ @Override
+ public ClassVisitor createClassVisitor(ClassContext classContext, ClassVisitor classVisitor) {
+ Params params = getParameters().get();
+ String namespace = params.getNamespace().get();
+ List libraryNamespaces = params.getLibraryNamespaces().orElse(Collections.emptyList()).get();
+
+ if (libraryNamespaces.isEmpty()) {
+ return classVisitor;
+ }
+
+ String targetRClass = namespace.replace(".", "/") + "/R";
+ String targetRSubclass = namespace.replace(".", "/") + "/R$";
+
+ Set libraryRClasses = libraryNamespaces.stream()
+ .map(it -> it.replace(".", "/") + "/R")
+ .collect(Collectors.toSet());
+ List libraryRSubclasses = libraryNamespaces.stream()
+ .map(it -> it.replace(".", "/") + "/R$")
+ .collect(Collectors.toList());
+
+ Remapper remapper = new Remapper() {
+ @Override
+ public String map(String internalName) {
+ if (internalName == null) {
+ return null;
+ }
+ if (libraryRClasses.contains(internalName)) {
+ return targetRClass;
+ }
+ for (String libraryRSubclass : libraryRSubclasses) {
+ if (internalName.startsWith(libraryRSubclass)) {
+ return StringsKt.replaceFirst(internalName, libraryRSubclass, targetRSubclass, false);
+ }
+ }
+ return super.map(internalName);
+ }
+ };
+ return new ClassRemapper(classVisitor, remapper);
+ }
+
+ @Override
+ public boolean isInstrumentable(ClassData classData) {
+ return true;
+ }
+ }
+}
diff --git a/source/src/main/java/com/kezong/fataar/RClassesTransform.java b/source/src/main/java/com/kezong/fataar/RClassesTransform.java
index c21a72d0..d6bfc8ec 100644
--- a/source/src/main/java/com/kezong/fataar/RClassesTransform.java
+++ b/source/src/main/java/com/kezong/fataar/RClassesTransform.java
@@ -8,8 +8,6 @@
import com.android.build.api.transform.TransformInput;
import com.android.build.api.transform.TransformInvocation;
import com.android.build.api.transform.TransformOutputProvider;
-import com.android.build.gradle.internal.pipeline.TransformManager;
-import com.google.common.collect.ImmutableSet;
import org.gradle.api.Project;
@@ -21,6 +19,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -89,12 +88,16 @@ public String getName() {
@Override
public Set getInputTypes() {
- return TransformManager.CONTENT_CLASS;
+ HashSet set = new HashSet<>();
+ set.add(QualifiedContent.DefaultContentType.CLASSES);
+ return set;
}
@Override
public Set super QualifiedContent.Scope> getScopes() {
- return ImmutableSet.of(QualifiedContent.Scope.PROJECT);
+ HashSet scopes = new HashSet<>();
+ scopes.add(QualifiedContent.Scope.PROJECT);
+ return scopes;
}
@Override
diff --git a/source/upload.gradle b/source/upload.gradle
index 03cbfd67..8696836d 100644
--- a/source/upload.gradle
+++ b/source/upload.gradle
@@ -99,12 +99,12 @@ publishing {
// The username and password we've fetched earlier
credentials {
- username ossrhUsername
- password ossrhPassword
+ //username ossrhUsername
+ //password ossrhPassword
}
}
}
}
signing {
sign publishing.publications
-}
\ No newline at end of file
+}