0%

构建编译Task替换2

根据TaskManager中的Task构建方式进行替换Task

源码

DefaultTaskContainer源码

1
2
3
4
5
public <T extends Task> T create(String name, Class<T> type, Action<? super T> configuration) throws InvalidUserDataException {
T task = this.create(name, type);
configuration.execute(task);
return task;
}

TaskManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void createBuildConfigTask(@NonNull TaskFactory tasks, @NonNull VariantScope scope) {
AndroidTask<GenerateBuildConfig> generateBuildConfigTask =
androidTasks.create(tasks, new GenerateBuildConfig.ConfigAction(scope));
scope.setGenerateBuildConfigTask(generateBuildConfigTask);
scope.getSourceGenTask().dependsOn(tasks, generateBuildConfigTask.getName());
if (scope.getVariantConfiguration().getType().isForTesting()) {
// in case of a test project, the manifest is generated so we need to depend
// on its creation.

generateBuildConfigTask.dependsOn(tasks, scope.getManifestProcessorTask());
} else {
generateBuildConfigTask.dependsOn(tasks, scope.getCheckManifestTask());
}
}

实现

ReplaceTask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public abstract class ReplaceTask<T extends Task, R extends Task> {
public ReplaceTask() {
}

public abstract Class<R> getReplaceTaskClass();

public abstract Class<T> getCustomTaskClass();

public abstract Task createTask(Task task,Project project,VariantScope variantScope);


public void replace(Project project) {
List<Task> replaceTasks = new ArrayList<>();
for (Task task : project.getTasks()) {
if (task.getClass().getName().startsWith(getReplaceTaskClass().getName())) {
replaceTasks.add(task);
}
}

for (Task replaceTask : replaceTasks) {
project.getTasks().remove(replaceTask);
}

for (Task replaceTask : replaceTasks) {
VariantScope variantScope = getVariantScope(project,((BaseTask)replaceTask).getVariantName());
Task task = createTask(replaceTask,project, variantScope);
task.dependsOn(replaceTask.getDependsOn());
}

}

public VariantScope getVariantScope(Project project, String variantName) {
List<VariantScope> variantScopes = null;
if (project.getPlugins().hasPlugin(AppPlugin.class)) {
variantScopes = project.getPlugins().getPlugin(AppPlugin.class).getVariantManager().getVariantScopes();
} else if(project.getPlugins().hasPlugin(LibraryPlugin.class)){
variantScopes = project.getPlugins().getPlugin(LibraryPlugin.class).getVariantManager().getVariantScopes();
}

if(variantScopes == null || variantScopes.isEmpty()){
throw new RuntimeException("scope ex");
}

for (VariantScope variantScope: variantScopes){
if(variantScope.getFullVariantName().equals(variantName)){
return variantScope;
}
}
return null;
}
}

GenerateBuildConfigExt

1
2
3
4
5
6
7
8
public class GenerateBuildConfigExt extends GenerateBuildConfig {

@TaskAction
void process() {
System.out.println("测试");
}

}

GenerateBuildConfigReplace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class GenerateBuildConfigReplace extends ReplaceTask<GenerateBuildConfigExt, GenerateBuildConfig>{
@Override
public Class<GenerateBuildConfig> getReplaceTaskClass() {
return GenerateBuildConfig.class;
}

@Override
public Class<GenerateBuildConfigExt> getCustomTaskClass() {
return GenerateBuildConfigExt.class;
}

@Override
public Task createTask(Task task,Project project, VariantScope variantScope) {
return project.getTasks().create(task.getName(), GenerateBuildConfigExt.class, new GenerateBuildConfigExt.ConfigAction(variantScope));
}
}

运行

image.png

问题

  • Task中将会有两个@TaskAction,并且子类访问不到父类中的私有属性
  • 部分父类ConfigAction是final修饰,我们无法继承

综上,这种方式也是存在一定的局限性