Android 编译流程解析01-AppPlugin初始化

简介

Android编译由Gradle插件来完成。
在平时开发中,我们都知道,添加以下Gradle插件,我们就可以编译Android项目。

dependencies {
     
    classpath 'com.android.tools.build:gradle:3.0.1'
}

apply plugin: 'com.android.application' //主项目
apply plugin: 'com.android.library' //Library

那我们要如何看到com.android.tools.build:gradle的源码呢?
我们可以在app的gradle引入

compileOnly "com.android.tools.build:gradle:3.0.1"

然后就可以在External Libraries中,看到源码了。
Android 编译流程解析01-AppPlugin初始化_第1张图片
接着,我们来看下com.android.application.properties

implementation-class=com.android.build.gradle.AppPlugin

可以看到,AppPlugin这个类,即com.android.application的入口是AppPlugin

public class AppPlugin extends BasePlugin implements Plugin<Project> {
     
	//...
}

我们来看其中的apply方法

@Override
public void apply(@NonNull Project project) {
     
    super.apply(project);
}

可以看到,其调用了父类BasePlugin,我们来看BasePlugin的apply方法

protected void apply(@NonNull Project project) {
     
 	// We run by default in headless mode, so the JVM doesn't steal focus.
    System.setProperty("java.awt.headless", "true");

    project.getPluginManager().apply(AndroidBasePlugin.class);
    checkPluginVersion();

    TaskInputHelper.enableBypass();

    this.project = project;
    this.projectOptions = new ProjectOptions(project);
    ExecutionConfigurationUtil.setThreadPoolSize(projectOptions);
    checkPathForErrors();
    checkModulesForErrors();

    PluginInitializer.initialize(project, projectOptions);
    ProfilerInitializer.init(project, projectOptions);
    //获得threadRecorder
    threadRecorder = ThreadRecorder.get();

    ProcessProfileWriter.getProject(project.getPath())
            .setAndroidPluginVersion(Version.ANDROID_GRADLE_PLUGIN_VERSION)
            .setAndroidPlugin(getAnalyticsPluginType())
            .setPluginGeneration(GradleBuildProject.PluginGeneration.FIRST);

	//记录一个方法的耗时,内部会调用configureProject()
    threadRecorder.record(
            ExecutionType.BASE_PLUGIN_PROJECT_CONFIGURE,
            project.getPath(),
            null,
            this::configureProject);
	//记录一个方法的耗时,内部会调用configureExtension()
    threadRecorder.record(
            ExecutionType.BASE_PLUGIN_PROJECT_BASE_EXTENSION_CREATION,
            project.getPath(),
            null,
            this::configureExtension);
	//记录一个方法的耗时,内部会调用createTasks()
    threadRecorder.record(
            ExecutionType.BASE_PLUGIN_PROJECT_TASKS_CREATION,
            project.getPath(),
            null,
            this::createTasks);
}

可以看到,这里主要执行了三个方法: configureProject()configureExtensioncreateTasks()

configureProject

该方法用来配置我们的Project

private void configureProject() {
     
        extraModelInfo = new ExtraModelInfo(projectOptions, project.getLogger());
        checkGradleVersion();

		//创建SdkHandler,SdkHandler需要用到android.jar这个包
        sdkHandler = new SdkHandler(project, getLogger());

        if (!project.getGradle().getStartParameter().isOffline()
                && projectOptions.get(BooleanOption.ENABLE_SDK_DOWNLOAD)
                && !projectOptions.get(BooleanOption.IDE_INVOKED_FROM_IDE)) {
     
            SdkLibData sdkLibData = SdkLibData.download(getDownloader(), getSettingsController());
            sdkHandler.setSdkLibData(sdkLibData);
        }
		//创建一个构建的对象 AndroidBuilder
        androidBuilder = new AndroidBuilder(
                project == project.getRootProject() ? project.getName() : project.getPath(),
                creator,
                new GradleProcessExecutor(project),
                new GradleJavaProcessExecutor(project),
                extraModelInfo,
                getLogger(),
                isVerbose());
		//创建一个构建的对象 DataBindingBuilder
        dataBindingBuilder = new DataBindingBuilder();
        dataBindingBuilder.setPrintMachineReadableOutput(
                extraModelInfo.getErrorFormatMode() ==
                        ExtraModelInfo.ErrorFormatMode.MACHINE_PARSABLE);

		//关联Java和Jacoco(单元测试) Plugin
        // Apply the Java and Jacoco plugins.
        project.getPlugins().apply(JavaBasePlugin.class);
        project.getPlugins().apply(JacocoPlugin.class);

        project.getTasks()
                .getByName("assemble")
                .setDescription(
                        "Assembles all variants of all applications and secondary packages.");

        // call back on execution. This is called after the whole build is done (not
        // after the current project is done).
        // This is will be called for each (android) projects though, so this should support
        // being called 2+ times.
        project.getGradle()
                .addBuildListener(
                        new BuildListener() {
     
                            @Override
                            public void buildStarted(Gradle gradle) {
     
                                TaskInputHelper.enableBypass();
                            }

                            @Override
                            public void settingsEvaluated(Settings settings) {
     }

                            @Override
                            public void projectsLoaded(Gradle gradle) {
     }

                            @Override
                            public void projectsEvaluated(Gradle gradle) {
     }

                            @Override
                            public void buildFinished(BuildResult buildResult) {
     
                                // Do not run buildFinished for included project in composite build.
                                if (buildResult.getGradle().getParent() != null) {
     
                                    return;
                                }
                                ExecutorSingleton.shutdown();
                                sdkHandler.unload();
                                threadRecorder.record(
                                        ExecutionType.BASE_PLUGIN_BUILD_FINISHED,
                                        project.getPath(),
                                        null,
                                        () -> {
     
                                        	//清除缓存
                                            PreDexCache.getCache()
                                                    .clear(
                                                            FileUtils.join(
                                                                    project.getRootProject()
                                                                            .getBuildDir(),
                                                                    FD_INTERMEDIATES,
                                                                    "dex-cache",
                                                                    "cache.xml"),
                                                            getLogger());
                                            Main.clearInternTables();
                                        });
                            }
                        });

        project.getGradle()
                .getTaskGraph()
                .addTaskExecutionGraphListener(
                        taskGraph -> {
     
                            TaskInputHelper.disableBypass();

                            for (Task task : taskGraph.getAllTasks()) {
     
                                if (task instanceof TransformTask) {
     
                                    Transform transform = ((TransformTask) task).getTransform();
                                    if (transform instanceof DexTransform) {
     
                                        PreDexCache.getCache()
                                                .load(
                                                        FileUtils.join(
                                                                project.getRootProject()
                                                                        .getBuildDir(),
                                                                FD_INTERMEDIATES,
                                                                "dex-cache",
                                                                "cache.xml"));
                                        break;
                                    }
                                }
                            }
                        });
    }

configureExtension

配置Extension扩展,也就是我们平时通过android{}来进行配置的内容

private void configureExtension() {
     
	//创建4个对象容器
	//buildType节点
   final NamedDomainObjectContainer<BuildType> buildTypeContainer =
           project.container(
                   BuildType.class,
                   new BuildTypeFactory(instantiator, project, extraModelInfo));
   //productFlavor节点
   final NamedDomainObjectContainer<ProductFlavor> productFlavorContainer =
           project.container(
                   ProductFlavor.class,
                   new ProductFlavorFactory(
                           instantiator, project, project.getLogger(), extraModelInfo));
	//签名
   final NamedDomainObjectContainer<SigningConfig> signingConfigContainer =
           project.container(SigningConfig.class, new SigningConfigFactory(instantiator));
	//VariantOutput,变体,比如debug、release、也可和productFlavor组合
   final NamedDomainObjectContainer<BaseVariantOutput> buildOutputs =
           project.container(BaseVariantOutput.class);

   project.getExtensions().add("buildOutputs", buildOutputs);
	//创建Extension
   extension =
           createExtension(
                   project,
                   projectOptions,
                   instantiator,
                   androidBuilder,
                   sdkHandler,
                   buildTypeContainer,
                   productFlavorContainer,
                   signingConfigContainer,
                   buildOutputs,
                   extraModelInfo);

   ndkHandler =
           new NdkHandler(
                   project.getRootDir(),
                   null, /* compileSkdVersion, this will be set in afterEvaluate */
                   "gcc",
                   "" /*toolchainVersion*/,
                   false /* useUnifiedHeaders */);


   @Nullable
   FileCache buildCache = BuildCacheUtils.createBuildCacheIfEnabled(project, projectOptions);

   GlobalScope globalScope =
           new GlobalScope(
                   project,
                   projectOptions,
                   androidBuilder,
                   extension,
                   sdkHandler,
                   ndkHandler,
                   registry,
                   buildCache);

   variantFactory = createVariantFactory(globalScope, instantiator, androidBuilder, extension);
	//创建taskManager,会管理我们Task的创建
   taskManager =
           createTaskManager(
                   globalScope,
                   project,
                   projectOptions,
                   androidBuilder,
                   dataBindingBuilder,
                   extension,
                   sdkHandler,
                   ndkHandler,
                   registry,
                   threadRecorder);
	//创建variantManager
   variantManager =
           new VariantManager(
                   globalScope,
                   project,
                   projectOptions,
                   androidBuilder,
                   extension,
                   variantFactory,
                   taskManager,
                   threadRecorder);

   registerModels(registry, globalScope, variantManager, extension, extraModelInfo);

   // map the whenObjectAdded callbacks on the containers.
   signingConfigContainer.whenObjectAdded(variantManager::addSigningConfig);

   buildTypeContainer.whenObjectAdded(
           buildType -> {
     
               SigningConfig signingConfig =
                       signingConfigContainer.findByName(BuilderConstants.DEBUG);
               buildType.init(signingConfig);
               variantManager.addBuildType(buildType);
           });

   productFlavorContainer.whenObjectAdded(variantManager::addProductFlavor);

   // map whenObjectRemoved on the containers to throw an exception.
   signingConfigContainer.whenObjectRemoved(
           new UnsupportedAction("Removing signingConfigs is not supported."));
   buildTypeContainer.whenObjectRemoved(
           new UnsupportedAction("Removing build types is not supported."));
   productFlavorContainer.whenObjectRemoved(
           new UnsupportedAction("Removing product flavors is not supported."));

   // create default Objects, signingConfig first as its used by the BuildTypes.
   variantFactory.createDefaultComponents(
           buildTypeContainer, productFlavorContainer, signingConfigContainer);
}

createTasks

该方法用来创建一系列Task

private void createTasks() {
     
//记录耗时,并调用createTasksBeforeEvaluate()
//createTasksBeforeEvaluate会创建很多Task,但是都是和系统相关的
//比如卸载应用,系统检测,连接设备等
 threadRecorder.record(
            ExecutionType.TASK_MANAGER_CREATE_TASKS,
            project.getPath(),
            null,
            () ->
                    taskManager.createTasksBeforeEvaluate(
                            new TaskContainerAdaptor(project.getTasks())));
	
    project.afterEvaluate( //afterEvaluate调用时,项目已经配置好了
            project ->
            		//记录耗时,并调用createAndroidTasks()来创建Task,不同的productFlavor、buildTypes创建的task也不同
                    threadRecorder.record(
                            ExecutionType.BASE_PLUGIN_CREATE_ANDROID_TASKS,
                            project.getPath(),
                            null,
                            () -> createAndroidTasks(false)));
}

来看createAndroidTasks()

//...
threadRecorder.record(
	ExecutionType.VARIANT_MANAGER_CREATE_ANDROID_TASKS,
    project.getPath(),
    null,
    () -> {
     
    	//调用variantManager的createAndroidTasks()
        variantManager.createAndroidTasks();
        ApiObjectFactory apiObjectFactory =
                new ApiObjectFactory(
                        androidBuilder,
                        extension,
                        variantFactory,
                        instantiator,
                        project.getObjects());
        for (VariantScope variantScope : variantManager.getVariantScopes()) {
     
            BaseVariantData variantData = variantScope.getVariantData();
                  apiObjectFactory.create(variantData);
              }
          });
//...

来看variantManager.createAndroidTasks()

public void createAndroidTasks() {
     
        variantFactory.validateModel(this);
        variantFactory.preVariantWork(project);

        final TaskFactory tasks = new TaskContainerAdaptor(project.getTasks());
        if (variantScopes.isEmpty()) {
     
            recorder.record(
                    ExecutionType.VARIANT_MANAGER_CREATE_VARIANTS,
                    project.getPath(),
                    null /*variantName*/,
                    //创建出所有的variant变体
                    this::populateVariantDataList);
        }

        // Create top level test tasks.
        recorder.record(
                ExecutionType.VARIANT_MANAGER_CREATE_TESTS_TASKS,
                project.getPath(),
                null /*variantName*/,
                //创建测试使用的方法
                () -> taskManager.createTopLevelTestTasks(tasks, !productFlavors.isEmpty()));

        for (final VariantScope variantScope : variantScopes) {
     
            recorder.record(
                    ExecutionType.VARIANT_MANAGER_CREATE_TASKS_FOR_VARIANT,
                    project.getPath(),
                    variantScope.getFullVariantName(),
                    //根据Variant变体创建出相应的一堆Task
                    () -> createTasksForVariantData(tasks, variantScope));
        }
		//创建依赖报告、签名报告的Task
        taskManager.createReportTasks(tasks, variantScopes);
    }

来看createTasksForVariantData

public void createTasksForVariantData(
		final TaskFactory tasks, final VariantScope variantScope) {
     
	final BaseVariantData variantData = variantScope.getVariantData();
	final VariantType variantType = variantData.getType();

	final GradleVariantConfiguration variantConfig = variantScope.getVariantConfiguration();

	//添加assemble开头的一系列Task
	final BuildTypeData buildTypeData = buildTypes.get(variantConfig.getBuildType().getName());
	if (buildTypeData.getAssembleTask() == null) {
     
		buildTypeData.setAssembleTask(taskManager.createAssembleTask(tasks, buildTypeData));
	}
	tasks.named("assemble", new Action<Task>() {
     
		@Override
		public void execute(Task task) {
     
			assert buildTypeData.getAssembleTask() != null;
			task.dependsOn(buildTypeData.getAssembleTask().getName());
		}
	});

	createAssembleTaskForVariantData(tasks, variantData);
	//是否是测试的Task
	if (variantType.isForTesting()) {
     
		//...
	} else {
     
		//创建一堆Task
		taskManager.createTasksForVariantScope(tasks, variantScope);
	}
}

可以看到,最终会调用createTasksForVariantScope()

@Override
public void createTasksForVariantScope(
		@NonNull final TaskFactory tasks, @NonNull final VariantScope variantScope) {
     
	BaseVariantData variantData = variantScope.getVariantData();
	assert variantData instanceof ApplicationVariantData;

	createAnchorTasks(tasks, variantScope);
	//检查Manifest是否符合规范 -> PreBuildTask
	createCheckManifestTask(tasks, variantScope);

	handleMicroApp(tasks, variantScope);

	// Create all current streams (dependencies mostly at this point)
	createDependencyStreams(tasks, variantScope);

	// Add a task to publish the applicationId.
	createApplicationIdWriterTask(tasks, variantScope);

	// Add a task to process the manifest(s)
	recorder.record(
			//合并Manifest
			ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createMergeApkManifestsTask(tasks, variantScope));

	// Add a task to create the res values
	recorder.record(
			//生成res values
			ExecutionType.APP_TASK_MANAGER_CREATE_GENERATE_RES_VALUES_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createGenerateResValuesTask(tasks, variantScope));

	// Add a task to compile renderscript files.
	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_CREATE_RENDERSCRIPT_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createRenderscriptTask(tasks, variantScope));

	// Add a task to merge the resource folders
	//合并Resource文件
	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			(Recorder.VoidBlock) () -> createMergeResourcesTask(tasks, variantScope, true));

	// Add a task to merge the asset folders
	recorder.record(
			//合并Assert文件
			ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_ASSETS_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createMergeAssetsTask(tasks, variantScope, null));

	// Add a task to create the BuildConfig class
	recorder.record(
			//创建BuildConfig.java
			ExecutionType.APP_TASK_MANAGER_CREATE_BUILD_CONFIG_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createBuildConfigTask(tasks, variantScope));

	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_PROCESS_RES_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> {
     
				// Add a task to process the Android Resources and generate source files
				createApkProcessResTask(tasks, variantScope);

				// Add a task to process the java resources
				createProcessJavaResTask(tasks, variantScope);
			});

	recorder.record(
			//创建AIDL
			ExecutionType.APP_TASK_MANAGER_CREATE_AIDL_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createAidlTask(tasks, variantScope));

	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_SHADER_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createShaderTask(tasks, variantScope));

	// Add NDK tasks
	if (!isComponentModelPlugin()) {
     
		recorder.record(
				ExecutionType.APP_TASK_MANAGER_CREATE_NDK_TASK,
				project.getPath(),
				variantScope.getFullVariantName(),
				() -> createNdkTasks(tasks, variantScope));
	} else {
     
		if (variantData.compileTask != null) {
     
			variantData.compileTask.dependsOn(getNdkBuildable(variantData));
		} else {
     
			variantScope.getCompileTask().dependsOn(tasks, getNdkBuildable(variantData));
		}
	}
	variantScope.setNdkBuildable(getNdkBuildable(variantData));

	// Add external native build tasks

	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_EXTERNAL_NATIVE_BUILD_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> {
     
				createExternalNativeBuildJsonGenerators(variantScope);
				createExternalNativeBuildTasks(tasks, variantScope);
			});

	// Add a task to merge the jni libs folders
	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_JNILIBS_FOLDERS_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createMergeJniLibFoldersTasks(tasks, variantScope));

	// Add data binding tasks if enabled
	createDataBindingTasksIfNecessary(tasks, variantScope);

	// Add a compile task
	recorder.record(
			//编译代码
			ExecutionType.APP_TASK_MANAGER_CREATE_COMPILE_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> addCompileTask(tasks, variantScope));

	createStripNativeLibraryTask(tasks, variantScope);

	if (variantScope.getOutputScope().getMultiOutputPolicy().equals(MultiOutputPolicy.SPLITS)) {
     
		if (extension.getBuildToolsRevision().getMajor() < 21) {
     
			throw new RuntimeException(
					"Pure splits can only be used with buildtools 21 and later");
		}

		recorder.record(
				ExecutionType.APP_TASK_MANAGER_CREATE_SPLIT_TASK,
				project.getPath(),
				variantScope.getFullVariantName(),
				() -> createSplitTasks(tasks, variantScope));
	}

	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_PACKAGING_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> {
     
				AndroidTask<BuildInfoWriterTask> buildInfoWriterTask =
						createInstantRunPackagingTasks(tasks, variantScope);
				createPackagingTask(tasks, variantScope, buildInfoWriterTask);
			});

	// create the lint tasks.
	recorder.record(
			ExecutionType.APP_TASK_MANAGER_CREATE_LINT_TASK,
			project.getPath(),
			variantScope.getFullVariantName(),
			() -> createLintTasks(tasks, variantScope));
}

可以看到,这里创建了很多的Task。
至此,我们对AppPlugin的初始化工作有了一定的了解。
下篇文章我们来详见讲解下AppPlugin中的Task。

Android 编译流程解析系列
Android 编译流程解析01-AppPlugin初始化
Android 编译流程解析02-相关Task解析
Android 编译流程解析03-手动编译Apk

你可能感兴趣的:(Android深度,android,gradle,编译流程,AppPlugin,解析)