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
中,看到源码了。
接着,我们来看下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方法
@Overridepublic 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()
、configureExtension
、createTasks()
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开头的一系列Taskfinal BuildTypeData buildTypeData = buildTypes.get(variantConfig.getBuildType().getName());if (buildTypeData.getAssembleTask() == null) { buildTypeData.setAssembleTask(taskManager.createAssembleTask(tasks, buildTypeData));}tasks.named("assemble", new Action<Task>() { @Overridepublic void execute(Task task) { assert buildTypeData.getAssembleTask() != null;task.dependsOn(buildTypeData.getAssembleTask().getName());}});createAssembleTaskForVariantData(tasks, variantData);//是否是测试的Taskif (variantType.isForTesting()) { //...} else { //创建一堆TasktaskManager.createTasksForVariantScope(tasks, variantScope);}}
可以看到,最终会调用createTasksForVariantScope()
@Overridepublic void createTasksForVariantScope(@NonNull final TaskFactory tasks, @NonNull final VariantScope variantScope) { BaseVariantData variantData = variantScope.getVariantData();assert variantData instanceof ApplicationVariantData;createAnchorTasks(tasks, variantScope);//检查Manifest是否符合规范 -> PreBuildTaskcreateCheckManifestTask(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(//合并ManifestExecutionType.APP_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK,project.getPath(),variantScope.getFullVariantName(),() -> createMergeApkManifestsTask(tasks, variantScope));// Add a task to create the res valuesrecorder.record(//生成res valuesExecutionType.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 foldersrecorder.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 classrecorder.record(//创建BuildConfig.javaExecutionType.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 filescreateApkProcessResTask(tasks, variantScope);// Add a task to process the java resourcescreateProcessJavaResTask(tasks, variantScope);});recorder.record(//创建AIDLExecutionType.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 tasksif (!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 tasksrecorder.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 foldersrecorder.record(ExecutionType.APP_TASK_MANAGER_CREATE_MERGE_JNILIBS_FOLDERS_TASK,project.getPath(),variantScope.getFullVariantName(),() -> createMergeJniLibFoldersTasks(tasks, variantScope));// Add data binding tasks if enabledcreateDataBindingTasksIfNecessary(tasks, variantScope);// Add a compile taskrecorder.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平台开发-Power management-电源管理
- Android(安卓)MTP之服务端UsbService启动
- [Gradle] Gradle 构建 android 应用常见问题解决指南
- Android中的Handler、Looper、Message简要分析
- android如何调用显示和隐藏系统默认的输入法
- Android(安卓)调用相册 拍照 实现系统控件缩放 切割图片
- (备忘)Android(安卓)app中调用启动其他应用(系统应用和第三方应用)
- 使用eclipse创建android工程时得到警告
- [Android] 无法创建项目问题解决