自定義Gradle插件

??最近在學習字節(jié)碼插樁技術(shù),利用字節(jié)碼插樁技術(shù),我們可以在編譯時期對字節(jié)碼進行修改,達到完成一些特殊需求,比如埋點(可以聲明一個BaseActivity,在onCreate和onDestory中進行埋點);統(tǒng)計函數(shù)執(zhí)行時間;熱修復,ButterKnief、Dagger等也用到了字節(jié)碼插樁技術(shù)。
??在Android中要使用字節(jié)碼插樁技術(shù)需要完成三步:

  • 自定義Gradle插件 :自定義插件,重寫apply方法,注冊自定義Transform
  • Transform Api使用:自定義Ttransform,在transform方法中實現(xiàn)處理邏輯
  • Asm的使用: 在transform中使用Asm插入字節(jié)碼
    ??本文是實現(xiàn)第一步,自定義Gradle。
    ??實現(xiàn)自定義Gradle插件主要有三種方式:
    1.在build.gradle中定義,直接在module的build.gradle中實現(xiàn),缺點:只能在本項目中使用,不好復用。
    2.buildSrc中使用。這種方式需要在項目中新建一個model命名為buildSrc,這個目錄就用來存放自定義插件,缺點:只能在本項目中使用,不好復用。
    3.獨立Module中使用。這種方式就是完全獨立開發(fā)一個Module,并且可以上傳至maven庫,可以隨便用。
    由于三種方式實現(xiàn)都差不多,前兩種局限性比較大,所以本文只對第三種進行記錄。
    1、新建Android Module選擇Android Library類型即可
    ??除去src/main和build.gradle其余文件都刪除,并清除build.gradle內(nèi)容,將以下內(nèi)容填入build.gradle,并同步gradle
apply plugin: 'groovy'

dependencies {
    //gradle sdk
    implementation gradleApi()
    //groovy sdk
    implementation localGroovy()
}

2、新建groovy文件,實現(xiàn)插件邏輯
??在src/main目錄下新建groovy目錄,在groovy目錄下新建com.example.clean目錄(名字自取即可),在該目錄下新建CleanPlugin.groovy文件,文件有一個綠色的G標記,表示系統(tǒng)識別為groovy文件,可以導入gradle api。如果沒有出現(xiàn)綠色標志,可以將文件名改為小寫試試。

新建插件文件

??這個cleanplugin.groovy就是我們要實現(xiàn)插件的主要邏輯,我們需要聲明一個類來實現(xiàn)Plugin<Project>接口,在apply中實現(xiàn)主要邏輯。

package com.example.clean
import org.gradle.api.Plugin
import org.gradle.api.Project;

class cleanplugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        println("clean plugin")
    }
}


??注意記得導入包目錄,否則會導致找不到插件實現(xiàn)類
3、聲明插件
??在src/main目錄下新建resource目錄,接著新建META-INF目錄,繼續(xù)新建gradle-plugins目錄,再新建com.example.firstplugin.properties文件(名字自取),注意文件名即為到時候其他項目中引用的插件名,在該文件中寫入如下內(nèi)容

//插件實現(xiàn)類
implementation-class=com.example.clean.cleanplugin

4、將插件上傳至maven庫
??在插件的build.gradle文件中添加插件groupid、version等參數(shù)和上傳maven地址

apply plugin: 'maven-publish'
publishing {
    publications {
        mavenJava(MavenPublication) {

            //其他項目使用插件時的方式:classpath 'com.example.clean:firstplug:1.0.0'
            //三個參數(shù)
            groupId 'com.example.clean'
            artifactId 'firstplug'
            version '1.0.0'

            from components.java

        }
    }
}

publishing {
    repositories {
        maven {
            // maven地址,可以是本地地址也可以是遠程地址
            url uri('C:/Android/repos')
        }
    }
}

最終build.gradle文件內(nèi)容如下:

apply plugin: 'groovy'
apply plugin: 'maven-publish'

dependencies {
    //gradle sdk
    implementation gradleApi()
    //groovy sdk
    implementation localGroovy()
}

publishing {
    publications {
        mavenJava(MavenPublication) {

            //其他項目使用插件時的方式:classpath 'com.example.clean:firstplug:1.0.0'
            //三個參數(shù)
            groupId 'com.example.clean'
            artifactId 'firstplug'
            version '1.0.0'

            from components.java

        }
    }
}

publishing {
    repositories {
        maven {
            // maven地址,可以是本地地址也可以是遠程地址
            url uri('C:/Android/repos')
        }
    }
}

??同步gradle,在右側(cè)的gradle目錄中,找到clean下的publish任務,并運行publish,將插件上傳至maven庫。


運行publish任務,上傳插件至maven庫

??運行成功后,在本地的repos目錄下可以找到上傳的插件


本地maven庫的插件

5、引用插件
??在項目的根build.gradle文件中,添加插件引用和maven庫地址,最終build.gradle文件內(nèi)容如下:

buildscript {
   
   repositories {
       google()
       jcenter()
       maven {//local maven repo path
           url uri('C:/Android/repos')
       }
   }
   dependencies {
       classpath 'com.android.tools.build:gradle:3.6.1'
       classpath 'com.example.clean:firstplug:1.0.0'
       

       // NOTE: Do not place your application dependencies here; they belong
       // in the individual module build.gradle files
   }
}

同步gradle,在app module的build.gradle文件中添加插件,如下:

//原文件的android插件
apply plugin: 'com.android.application'
//添加自定義插件,插件名即為com.example.firstplugin.properties文件名
apply plugin: 'com.example.firstplugin'

自定義插件名即為com.example.firstplugin.properties文件名,同步build.gradle,運行app下的bulid任務


插件運行成功

出現(xiàn)"clean plugin",即自定義插件中apply方法中輸出的日志,表示插件運行成功。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容