创建第一个适用于Android的自定义Gradle插件-第2部分:在构建时生成资源
A hands on tutorial to get started with adding custom functionality to your Android builds using Kotlin
动手教程,开始使用Kotlin向您的Android版本添加自定义功能
While the first part of this series focused on setting up the basic structure of a custom Gradle plugin, we will now move on to turn our work into something useful. The goal for this next instalment will be to create a Task capable of generating resources at build-time, which we will then use in our app.
虽然本系列的第一部分着重于设置自定义Gradle插件的基本结构,但我们现在将继续把我们的工作变成有用的东西。 下一部分的目标是创建一个能够在构建时生成资源的Task,然后将其用于我们的应用程序中。
Once again, if you want to skip all the reading and get straight to the code you can find it all on GitHub.
再一次,如果您想跳过所有阅读内容并直接阅读代码,可以在GitHub上找到所有内容。
Picking up where we left off:
在我们离开的地方接机:
In the first part of this write up we created a simple Task whose only purpose was to create a “Hello world” text file in our project directory. What we want to do now is extend this and turn it into something a little more useful. Specifically we want to generate some project resources at build-time, which we can then use in our app. To keep things simple we are going to generate three simple colours, the same process however can be used to create other resource types too.
在本文的第一部分中,我们创建了一个简单的Task,其唯一目的是在我们的项目目录中创建“ Hello world”文本文件。 我们现在想要做的就是扩展它,并将其转变为更有用的东西。 具体来说,我们希望在构建时生成一些项目资源,然后可以在我们的应用程序中使用它们。 为了使事情简单,我们将生成三种简单的颜色,但是相同的过程也可以用于创建其他资源类型。
Let’s start!
开始吧!
Although Gradle will create our colours at build-time, we’ll still need provide their definitions so that we can refer to them in our code. To do this we’ll declare three new entries in our colors.xm
file, just as we normally would, with the difference being that this time we will omit their values:
尽管Gradle将在构建时创建颜色,但是我们仍然需要提供它们的定义,以便我们可以在代码中引用它们。 为此,我们将像往常一样在colors.xm
文件中声明三个新条目,不同之处在于这一次我们将省略它们的值:
<color name="color1"/>
<color name="color2"/>
<color name="color3"/>
Next, because we will want to see what we have created, let us prepare our Activity to show these colours. Open the main_activity.xml
file and add three views, each to display one of the colours:
接下来,因为我们要查看创建的内容,所以让我们准备“活动”以显示这些颜色。 打开main_activity.xml
文件并添加三个视图,每个视图显示一种颜色:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Viewandroid:id="@+id/color_1_view"android:layout_width="match_parent"android:layout_height="100dp"android:background="@color/color1"app:layout_constraintBottom_toTopOf="@id/color_2_view"app:layout_constraintTop_toTopOf="parent" /><Viewandroid:id="@+id/color_2_view"android:layout_width="match_parent"android:layout_height="100dp"android:background="@color/color2"app:layout_constraintBottom_toTopOf="@id/color_3_view"app:layout_constraintTop_toBottomOf="@id/color_1_view" /><Viewandroid:id="@+id/color_3_view"android:layout_width="match_parent"android:layout_height="100dp"android:background="@color/color3"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintTop_toBottomOf="@id/color_2_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
This part is done. If you now run the app you should see a blank screen. This is as expected because our colours do not yet have value. We’ll remedy that soon enough.
这部分完成。 如果现在运行该应用程序,应该会看到一个空白屏幕。 这是预期的,因为我们的颜色还没有价值。 我们将尽快对此进行补救。
A little cleanup:
一点清理:
Before we get into the nitty gritty of building our Task, let’s do some cleanup. First of all I created a new file called Extensions.kt
. In this file I placed the two extensions we had defined in Part 1. Here I also added a simple function to write xml to a file with the necessary tags. The complete Extensions.kt
file should look something like this:
在进入构建任务的精髓之前,让我们做一些清理。 首先,我创建了一个名为Extensions.kt
的新文件。 在这个文件中,我放置了第1部分中定义的两个扩展。在这里,我还添加了一个简单的函数,用于将xml写入带有必需标记的文件中。 完整的Extensions.kt
文件应如下所示:
package extensionsimport com.android.build.gradle.AppExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.FeatureExtension
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.api.BaseVariant
import org.gradle.api.DomainObjectSet
import org.gradle.api.GradleException
import org.gradle.api.Project
import java.io.Filefun Project.android(): BaseExtension {val android = project.extensions.findByType(BaseExtension::class.java)if (android != null) {return android} else {throw GradleException("Project $name is not an Android project")}
}fun BaseExtension.variants(): DomainObjectSet<out BaseVariant> {return when (this) {is AppExtension -> {applicationVariants}is FeatureExtension -> {featureVariants}is LibraryExtension -> {libraryVariants}else -> throw GradleException("Unsupported BaseExtension type!")}
}// New extension to write pre-formatted xml within resource tags
fun File.writeXlmWithTags(body: String) {("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +"<resources>" +"$body\n" +"</resources>").also { resXml ->try {createNewFile()writeText(resXml)} catch (e: Exception) {throw GradleException(e.message)}}
}
Next we’ll actually remove most of what we had originally put in our plugin’s apply
method as we will re-define our Task in a standalone class. When done, our plugin class will look like this:
接下来,我们实际上将删除我们最初在插件apply
放入的大部分内容 方法,因为我们将在独立类中重新定义Task。 完成后,我们的插件类将如下所示:
import extensions.android
import extensions.variants
import org.gradle.api.Plugin
import org.gradle.api.Projectinternal class MyFirstPlugin : Plugin<Project> {override fun apply(project: Project) {project.android().variants().all { variant ->}}
}
Next we are going to add the new functionality for generating our resources.
接下来,我们将添加用于生成资源的新功能。
Create the new Task:
创建新任务:
We had originally declared the sole task of our plugin as a lambda. While this is fine for running quick experiments, it is always good practice to split every task of a plugin into a separate class. The following will take care of our current use-case:
我们最初将插件的唯一任务声明为lambda。 尽管这适合进行快速实验,但将插件的每个任务拆分为单独的类始终是一个好习惯。 以下内容将解决我们当前的用例:
import extensions.writeXlmWithTags
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.io.Fileinternal open class ColorsTask : DefaultTask(){@get:OutputFilelateinit var outputFile: File@get:Inputval colorsMap = mapOf("color1" to "#00ff00","color2" to "#ff0000","color3" to "#00ffff")@TaskActionfun makeResources() {colorsMap.entries.joinToString { (colorName, color) ->"\n <color name=\"$colorName\">$color</color>"}.also { xml ->outputFile.writeXlmWithTags(xml)}}
}
Note the following:
请注意以下几点:
The Task class needs to be declared
open
or Gradle will not be able to register it.必须声明Task类为
open
否则Gradle将无法注册它。- Colours are hardcoded for this example. In a real-life project — or in a future instalment of this tutorial
创建第一个适用于Android的自定义Gradle插件-第2部分:在构建时生成资源相关推荐
- Android如何自定义Gradle插件
Android-如何自定义gradle插件 自定义gradle插件可以实现定制自己的构建流程,以达到复用目的: ##1. 自定义插件方式 自定义插件有三种方式 添加脚步 在你的app项目的build. ...
- Gradle学习第一篇——自定义Gradle插件
纸上得来终觉浅,绝知此事要躬行. 自定义Gradle插件有三种方法,各有优劣处,同类博客文章很多但是有的语法已经过时了,笔者运行环境 Android Studio Dolphin && ...
- 使用AndroidStudio创建自定义gradle插件并被引用实战例子
项目中引入自定义Gradle plugin一般有三种方法: 直接写在 build.gradle中. plugin源码放到rootProjectDir/buildSrc/src/main/groovy目 ...
- Android组件化开发实践(九):自定义Gradle插件
本文紧接着前一章Android组件化开发实践(八):组件生命周期如何实现自动注册管理,主要讲解怎么通过自定义插件来实现组件生命周期的自动注册管理. 1. 采用groovy创建插件 新建一个Java L ...
- 【Android Gradle 插件】自定义 Gradle 插件优化图片 ① ( Android 中的 WebP 图片格式使用 | WebP 格式转换 | WebP 参考文档 )
文章目录 一.Android 中的 WebP 图片格式使用 二.WebP 格式转换 三.WebP 参考文档 Android Plugin DSL Reference 参考文档 : Android St ...
- Android 自定义gradle插件
android自定义gradle插件的步骤 1.首先我们新建一个android项目 2.然后新建一个android module a.删除一些不需要的文件目录,然后新建groovy,resources ...
- 通过自定义Gradle插件修改编译后的class文件
我的简书同步发布:通过自定义Gradle插件修改编译后的class文件 转载请注明出处:[huachao1001的专栏:http://blog.csdn.net/huachao1001] 或许你会觉得 ...
- 自定义Gradle插件之Hello World
自定义Gradle插件之"Hello World" 0.新建一个用于开发这个插件的文件夹 1.确定Plugin id Plugin id一般定义为java 包名. 由字母和数字及& ...
- android原生插件,适用于 Android 的原生 (C++) 插件
扩展 UnityPlayerActivity Java 代码 使用 Java 或 Kotlin 源文件作为插件 适用于 Android 的原生 (C++) 插件 Unity 支持用 C/C ++ 编写 ...
最新文章
- sql查询时间大于某一时间_查询时间从24分钟到2秒钟:记一次神奇的SQL优化
- Sina App Engine 介绍
- Inline Temp(内联临时变量)
- TensorFlow语义分割套件开源了ECCV18旷视科技BiSeNet实时分割算法
- Java JUC学习 - ConcurrentLinkedDeque 详解
- CMD发现一个得到字符串长度的方法
- c语言实验交换字母,C语言实验内容.doc
- [论文笔记]BI-DIRECTIONAL ATTENTION FLOW FOR MACHINE COMPREHENSION
- 有赞大裁员:裁员会超过1500人,加盟4年半的百度副总裁也已离职
- cocostudio html5,Cocostudio的简单使用:
- 认真测试直播软件,【转】如何测试直播软件
- 7天连锁酒店郑南雁:顺势创业者无为管理人
- 3C认证与电源PFC
- 计算机科学家与科学之路----2000年图灵奖得主美籍华人姚期智院士特邀报告
- web接口测试之GET与POST请求
- self的用法与意义(一)
- springboot 对接 淘宝联盟
- Java:Java vs Kotlin–Android应用程序开发的最佳语言?
- python的mapl画图y轴排_python中用Matplotlib做多个纵轴 (多y轴)
- 聊聊APP数据分析的那些思路
热门文章
- mooc翁凯C语言习题第七周(7-2)鞍点
- XMind软件非试用版本下载(亲测有效)
- python 如何计算平方、次方?平方根、方根?(math.pow()、math.sqrt())
- [经验技巧] 路由mini安装OpenWRT源的Transmission插件,实现PT下载(需SSH)
- TERA: Screen-to-Camera Image Code with Transparency, Efficiency, Robustness and Adaptability论文阅读
- envoy网络安全opa等
- 《第一行代码》总结之网络、服务(五)
- Ant Design Vue table表格点击行选中多选框
- vscode和ide(JetBrains全款)安装 Material Theme UI主题
- 综述:人类电生理的脑连接组学
- Android如何自定义Gradle插件