国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

詳解如何使用Android Studio開發Gradle插件

2019-10-22 18:24:46
字體:
來源:轉載
供稿:網友

緣由

首先說明一下為什么會有這篇文章。前段時間,插件化以及熱修復的技術很熱,Nuwa熱修復的工具NuwaGradle,攜程動態加載技術DynamicAPK,還有希望做最輕巧的插件化框架的Small。這三個App有一個共同的地方就是大量的使用了android/279246.html">Gradle這個強大的構建工具,除了攜程的框架外,另外兩個都發布了獨立的Gradle插件提供自動化構建插件,或者生成熱修復的補丁。所以學習一下Gradle插件的編寫還是一件十分有意義的事。

插件類型

Gradle的插件一般有這么幾種:

  1. 一種是直接在項目中的gradle文件里編寫,這種方式的缺點是無法復用插件代碼,在其他項目中還得復制一遍代碼(或者說說復制一遍文件)
  2. 另一種是在獨立的項目里編寫插件,然后發布到中央倉庫,之后直接引用就可以了,優點就是可復用。就和上面的Nuwa和Small一樣。

Gradle相關語法

本篇文章不會詳細說明Gradle相關的語法,如果要學習gradle相關的東西,請查看Gradle for Android

Gradle插件開發

Gradle插件是使用Groovy進行開發的,而Groovy其實是可以兼容Java的。Android Studio其實除了開發Android App外,完全可以勝任開發Gradle插件這一工作,下面來講講具體如何開發。

  1. 首先,新建一個Android項目。
  2. 之后,新建一個Android Module項目,類型選擇Android Library。
  3. 將新建的Module中除了build.gradle文件外的其余文件全都刪除,然后刪除build.gradle文件中的所有內容。
  4. 在新建的module中新建文件夾src,接著在src文件目錄下新建main文件夾,在main目錄下新建groovy目錄,這時候groovy文件夾會被Android識別為groovy源碼目錄。除了在main目錄下新建groovy目錄外,你還要在main目錄下新建resources目錄,同理resources目錄會被自動識別為資源文件夾。在groovy目錄下新建項目包名,就像Java包名那樣。resources目錄下新建文件夾META-INF,META-INF文件夾下新建gradle-plugins文件夾。這樣,就完成了gradle 插件的項目的整體搭建,之后就是小細節了。目前,項目的結構是這樣的。

Android,Studio,Gradle插件,Gradle,插件

打開Module下的build.gradle文件,輸入

apply plugin: 'groovy'apply plugin: 'maven'dependencies {  compile gradleApi()  compile localGroovy()}repositories {  mavenCentral()}

下面我們在包名下新建一個文件,命名為PluginImpl.groovy,注意有groovy后綴,然后在里面輸入,注意包名替換為你自己的包名。

package cn.edu.zafu.gradleimport org.gradle.api.Pluginimport org.gradle.api.Projectpublic class PluginImpl implements Plugin<Project> {  void apply(Project project) {    project.task('testTask') << {      println "Hello gradle plugin"    }  }}

然后在resources/META-INF/gradle-plugins目錄下新建一個properties文件,注意該文件的命名就是你只有使用插件的名字,這里命名為plugin.test.properties,在里面輸入

implementation-class=cn.edu.zafu.gradle.PluginImpl

注意包名需要替換為你自己的包名。

這樣就完成了最簡單的一個gradle插件,里面有一個叫testTask的Task,執行該task后會輸出一段文字,就像當初我們輸出HelloWorld一樣。

發布到本地倉庫

接著,我們需要將插件發布到maven中央倉庫,我們將插件發布到本地倉庫就好了,在module項目下的buidl.gradle文件中加入發布的代碼。

repositories {  mavenCentral()}group='cn.edu.zafu.gradle.plugin'version='1.0.0'uploadArchives {  repositories {    mavenDeployer {      repository(url: uri('../repo'))    }  }}

上面的group和version的定義會被使用,作為maven庫的坐標的一部分,group會被作為坐標的groupId,version會被作為坐標的version,而坐標的artifactId組成即module名,我們讓其取一個別名moduleName。然后maven本地倉庫的目錄就是當前項目目錄下的repo目錄。

這時候,右側的gradle Toolbar就會在module下多出一個task

Android,Studio,Gradle插件,Gradle,插件

點擊uploadArchives這個Task,就會在項目下多出一個repo目錄,里面存著這個gradle插件。

Android,Studio,Gradle插件,Gradle,插件

目錄就像上圖這樣,具體目錄結構和你的包名等一系列有關,time是我的module名。

發布到本地maven倉庫后,我們就使用它,在叫app的android項目下的gradle.build的文件中加入

buildscript {  repositories {    maven {      url uri('../repo')    }  }  dependencies {    classpath 'cn.edu.zafu.gradle.plugin:time:1.0.0'  }}apply plugin: 'plugin.test'

apply plugin后面引號內的名字就是前文plugin.test.properties文件的文件名。而class path后面引號里的內容,就是上面grade中定義的group,version以及moduleName所共同決定的,和maven是一樣的。

同步一下gradle,右側app下other分類下就會多出一個testTask,雙擊執行這個Task,控制臺就會輸出剛才我們輸入的字符串

Android,Studio,Gradle插件,Gradle,插件

發布到Jcenter倉庫

接下來我們將其發布到jcenter中央倉庫。

在項目根目錄下的build.gradle文件中加入。

dependencies {    classpath 'com.android.tools.build:gradle:2.0.0-beta6'    classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'    classpath 'com.github.dcendents:android-maven-plugin:1.2'  }

在項目根路徑下新建bintray.gradle文件,輸入

apply plugin: 'com.jfrog.bintray'apply plugin: 'maven-publish'def projectName = "timePlugin"def mavenDesc = 'your desc'def baseUrl = 'https://github.com/yourBaseUrl'def siteUrl = baseUrldef gitUrl = "${baseUrl}/yourGitUrl"def issueUrl = "${baseUrl}/yourGitIssueUrl"def licenseIds = ['Apache-2.0']def licenseNames = ['The Apache Software License, Version 2.0']def licenseUrls = ['http://www.apache.org/licenses/LICENSE-2.0.txt']def inception = '2016'def username = 'lizhangqu'install {  repositories {    mavenInstaller {      pom.project {        // Description        name projectName        description mavenDesc        url siteUrl        // Archive        groupId project.group        artifactId archivesBaseName        version project.version        // License        inceptionYear inception        licenses {          licenseNames.eachWithIndex { ln, li ->            license {              name ln              url licenseUrls[li]            }          }        }        developers {          developer {            name username          }        }        scm {          connection gitUrl          developerConnection gitUrl          url siteUrl        }      }    }  }}task sourcesJar(type: Jar) {  from sourceSets.main.allGroovy  classifier = 'sources'}task javadocJar(type: Jar, dependsOn: groovydoc) {  from groovydoc.destinationDir  classifier = 'javadoc'}artifacts {  archives javadocJar  archives sourcesJar}bintray {  user = BINTRAY_USER  key = BINTRAY_KEY  configurations = ['archives']  pkg {    repo = 'maven'    name = projectName    desc = mavenDesc    websiteUrl = siteUrl    issueTrackerUrl = issueUrl    vcsUrl = gitUrl    labels = ['gradle', 'plugin', 'time']    licenses = licenseIds    publish = true    publicDownloadNumbers = true  }}

將對應的描述性文字修改為你自己的信息,尤其是最前面的一系列的def定義,然后在gradle.properties文件中加入BINTRAY_USER和BINTRAY_KEY。

在你的module中apply該grade文件

apply from: '../bintray.gradle'

右側的gradle的toolbar就會多出幾個task

Android,Studio,Gradle插件,Gradle,插件

之后我們先運行other下的install這個task,再執行bintrayUpload這個task,如果不出意外,就上傳了,之后不要忘記到后臺add to jcenter。成功add到jcenter之后就會有link to jcenter的字樣

Android,Studio,Gradle插件,Gradle,插件

耐心等待add to center成功的消息,之后就可以直接引用了,將module下的gradle文件maven部分的定義

    maven {      url uri('../repo')    }

前面加入

jcenter()

最終的內容如下

buildscript {  repositories {    jcenter()    maven {      url uri('../repo')    }  }  dependencies {    classpath 'cn.edu.zafu.gradle.plugin:time:1.0.0'  }}apply plugin: 'plugin.test'

就是這么簡單,再次運行一下測試下是否成功。

最佳實踐

最佳實踐的來源是源自multidex,為什么呢,因為最近當方法數超了之后,如果選擇multidex,編譯的過程就會慢很多很多,為了檢測到底是哪一步的耗時,需要編寫一個插件來統計各個task執行的時間,因此就有了這么一個最佳實踐。

在PluginImpl同級目錄下新建TimeListener.groovy文件。輸入

package cn.edu.zafu.gradleimport org.gradle.BuildListenerimport org.gradle.BuildResultimport org.gradle.api.Taskimport org.gradle.api.execution.TaskExecutionListenerimport org.gradle.api.initialization.Settingsimport org.gradle.api.invocation.Gradleimport org.gradle.api.tasks.TaskStateimport org.gradle.util.Clockclass TimeListener implements TaskExecutionListener, BuildListener {  private Clock clock  private times = []  @Override  void beforeExecute(Task task) {    clock = new org.gradle.util.Clock()  }  @Override  void afterExecute(Task task, TaskState taskState) {    def ms = clock.timeInMs    times.add([ms, task.path])    task.project.logger.warn "${task.path} spend ${ms}ms"  }  @Override  void buildFinished(BuildResult result) {    println "Task spend time:"    for (time in times) {      if (time[0] >= 50) {        printf "%7sms %s/n", time      }    }  }  @Override  void buildStarted(Gradle gradle) {}  @Override  void projectsEvaluated(Gradle gradle) {}  @Override  void projectsLoaded(Gradle gradle) {}  @Override  void settingsEvaluated(Settings settings) {}}

然后將PluginImpl文件中的apply方法修改為

void apply(Project project) {    project.gradle.addListener(new TimeListener())  }

完成后打包發布到jcenter()。之后你只要引用了該插件,就會統計各個task執行的時間,比如運行app,就會輸出像下面的信息。

Android,Studio,Gradle插件,Gradle,插件

最佳實踐的末尾,推廣一下這個插件,這個插件我已經將其發布到jcenter倉庫,如果要使用的話加入下面的代碼即可

buildscript {  repositories {    jcenter()  }  dependencies {    classpath 'cn.edu.zafu.gradle.plugin:time:1.0.0'  }}apply plugin: 'plugin.time'

傳遞參數

上面的是小試牛刀了下,接下來我們需要獲得自定義的參數。

首先按照上面的步驟新建一個module。新建PluginExtension.groovy,輸入

public class PluginExtension {  def param1 = "param1 defaut"  def param2 = "param2 defaut"  def param3 = "param3 defaut"}

然后我們希望能傳入嵌套的參數,再新建一個PluginNestExtension.groovy,輸入

public class PluginNestExtension {  def nestParam1 = "nestParam1 defaut"  def nestParam2 = "nestParam2 defaut"  def nestParam3 = "nestParam3 defaut"}

然后新建一個CustomTask.groovy,繼承DefaultTask類,使用 @TaskAction注解標注實現的方法

public class CustomTask extends DefaultTask {  @TaskAction  void output() {    println "param1 is ${project.pluginExt.param1}"    println "param2 is ${project.pluginExt.param2}"    println "param3 is ${project.pluginExt.param3}"    println "nestparam1 is ${project.pluginExt.nestExt.nestParam1}"    println "nestparam2 is ${project.pluginExt.nestExt.nestParam2}"    println "nestparam3 is ${project.pluginExt.nestExt.nestParam3}"  }}

只是做了拿到了參數,然后做最簡單的輸出操作,使用 ${project.pluginExt.param1}和 ${project.pluginExt.nestExt.nestParam1}等拿到外部的參數。

別忘了在META-INF/gradle-plugins目錄下新建properties文件指定插件的接口實現類。

復制之前新建的PluginImpl.groovy到包下,修改apply方法

public class PluginImpl implements Plugin<Project> {  void apply(Project project) {    project.extensions.create('pluginExt', PluginExtension)    project.pluginExt.extensions.create('nestExt', PluginNestExtension)    project.task('customTask', type: CustomTask)  }}

將插件發布到本地maven后,進行引用。

buildscript {  repositories {    maven {      url uri('../repo')    }  }  dependencies {    classpath 'cn.edu.zafu.gradle.plugin:test:1.0.0'  }}apply plugin: 'plugin.test'

定義外部參數,這里我們定義了param1,param2,nestParam1,nestParam2,此外param3和nestParam3保持默認。

pluginExt {  param1 = 'app param1'  param2 = 'app param2'  nestExt{    nestParam1='app nestParam1'    nestParam2='app nestParam2'  }}

同步一下gradle,執行customTask。

Android,Studio,Gradle插件,Gradle,插件

上面的代碼很簡單,不用解釋也能看到,所以不再解釋了。

 源碼

最后上本篇文章的源碼 :GradlePlugin.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巧家县| 阜南县| 白水县| 舟山市| 石棉县| 白河县| 富锦市| 怀安县| 奉节县| 永寿县| 丹凤县| 夹江县| 收藏| 灌云县| 罗源县| 麻栗坡县| 山西省| 青海省| 和硕县| 加查县| 兴安盟| 金平| 临颍县| 从化市| 巧家县| 乳源| 沙坪坝区| 东辽县| 徐汇区| 杭锦后旗| 肥西县| 茂名市| 阳曲县| 名山县| 东乌珠穆沁旗| 新巴尔虎左旗| 米林县| 蒲城县| 皋兰县| 南涧| 皋兰县|