91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android自定義Gradle插件的實現、上傳和使用過程

發布時間:2021-07-08 15:55:55 來源:億速云 閱讀:494 作者:chen 欄目:開發技術

本篇內容介紹了“Android自定義Gradle插件的實現、上傳和使用過程”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、Gradle

我們知道在我們現在使用Android Stduio開發Android項目的時候,Android Studio是基于Gradle來幫助我們構建,管理項目的。
Gradle:Gradle是一個項目構建工具,用來幫助我們管理項目的依賴、打包、發布、部署等工作。
Gradle是通過如build.gradle這種gradle腳本來進行項目構建的,所以我們對項目的構建配置都是可以寫在gradle構建腳本中。
gradle構建腳本使用的是Groovy語言,Groovy語言也是一種jvm語言,最終也是編譯成class文件然后在jvm上執行,所以所有的Java語言的特性Groovy都支持,我們可以完全混寫Java和Groovy;

Gradle插件:

Gradle是一個構建項目的工具,但是Gradle本身只提供了一個核心框架,各種構建功能,比如編譯、依賴、打包等都是通過插件來完成的;
比如我們使用構建Android項目,就需要可以構建Android的gradle插件,所以我們在Android Studio中新建的每一個項目中都會在Project的build.gradle中都會引入構建Android項目的插件

dependencies {
        classpath "com.android.tools.build:gradle:4.1.3"
     }

這個Gradle插件是Google開發的gradle插件,插件中實際上是定義了一系列的Task,這些Task的執行對應的就是一系列的構建操作,如build(編譯)、install(安裝)等,而構建Android項目的gradle插件就定義了如build、install等Task;

Android自定義Gradle插件的實現、上傳和使用過程

除了使用Google以及其他開發好的一些插件,我們自己也可以開發Gradle插件,來幫助我們自動完成一些任務,比如多渠道打包插件,比如每次發布APK之前,可能還需要對APK進行加固,所以也可以開發一個加固插件;這樣,引入插件之后,在Gradle窗口中,直接點擊對應的Task,就會自動加固了,非常方便;
自定義插件也是使用Groovy語言來進行開發;

二、Groovy語法

上面我們說過Groovy是一種JVM語言,可以完全使用Java語法編寫代碼,但是Groovy也是 有自己的語法的,我們現在來學習一下Groovy的基本語法;

(1)Groovy中變量和方法的聲明

Groovy中通過def關鍵字來聲明變量和方法

  def a=1;

     def b="hello world";

     def int c=1;

     def test(){ //定義方法
        
         println("123");

         return 0;

     }

Groovy寫法相對來說比較隨意,很多東西都是可以省略的;
語句結尾的分號可以省略;
定義變量和方法時,變量的類型,和方法的返回值也可以省略;
Groovy中類型是弱化的,類型是可以動態推斷的;
Groovy中很多東西都是可以省略的:
方法調用時,括號也是可以省略的
方法的返回值,return都是可以省略的

def a=1;

    a="Hello World"   

    def test(a){

       println(a);

       1; //方法的返回值為1,返回值可以省略return 

    }

    test 1  //調用方法,可以省略括號

(2) Groovy中的數據類型

基本數據類型

Java中的基本數據類型,Groovy中都是有的;
但是不同的是,Groovy中的基本數據類型都是以對象的類型存在的;

 def int a=1;

    def double b=1.1;

    println(a.class);

    println(b.class);

對象類型
和Java中的對象類型是一樣的
這里把String類型單獨拿出來說下,因為Groovy中字符串的拼接比較有特色的,可以在字符串中使用 ${變量},來拼接變量的值

def a=1;

    String b="Hello ${a}" //字符串結果為 Hello 1

(3) 閉包Closure

Groovy中的閉包是一個開放的、匿名的代碼塊,可以接受參數,返回值并分配給變量

{ [closureParameters] -> statements }

//定義閉包

     def closure = { println("Hello World") }

     def closure1= { a,b -> a+b  }

     //調用閉包

     closure();

     closure.call(); //函數式調用或者使用call方式調用,這兩種方式調用閉包都是可以的

     def a=closure1(1,2);

     def a=closure1.call(1,2);

(4) Grovvy中的數據結構

前面我們說過Java中的東西,Grovvy中都是可以使用,所以Java中的數據結構,Grovvy中當然都是可以使用的;
這里主要學習下Grovvy中和Java中不同的常用語法:

List集合

//先寫一個Java中的語法

    List list=new ArrayList<>();

    list.add(1);

    list.add(2);
    
    //Groovy除了像Java中一樣寫法,還可以這樣來定義List

    def lists=[1,2,3];

    lists.add(4);

    lists.add(5);

    print(lists.class); //我們打印這個lists的class,它就是java.util.ArrayList

當然既然它就是Java中的ArrayList,當然還有remove,get等等API,這里就不一一列出來了,但是Groovy中List還提供了find查找的API,這個是Java中所沒有的

 def result=lists.find{
      
      return it%2==0;

    } //這里find查找方法傳入的參數是一個閉包,返回的是第一個能整除2的元素
    
 def results=lists.findAll {

      return it%2==0;

    } //查找List中所有的能整除2的元素 

 def resList=lists.sort {

        x1,x2->  return x1==x2?0:x1>x2?1:-1

    } //List中sort方法,傳入一個閉包參數,用于對List排序
    
lists.each{
       
       print(it+",");


    } //each方法遍歷List

List還有一些其他方法,這里可不一一列舉了

Map

 //先寫一個Java中Map的寫法

     Map map=new HashMap<>();
     
     map.put("a",1);
     
     map.put("b",2);

     //Groovy除了像Java中一樣寫法,還可以這樣來定義Map

     def map=["a":1,"b":2];

     prinlt(map.get("a")); //獲取某個鍵對應的值

     prinltn(map.a);//map.key 這種方式也可以獲取map中某個鍵的值

     println(map.getClass()); //這樣定義map,Map的默認數據類型是java.util.LinkedHashMap

                              //這里我們是使用map.getClass()來獲取map的類,而不能map.class來獲取

                              //是因為map有map.key這種用法,用來獲取map中鍵為key的值,所以如果寫map.class

                              //會被認為是獲取map中鍵為class的值,所以這里只能用map.getClass()來獲取map的class類型
    

    def v=map.find {

     if (it.getValue()==2){
          return it;
      }

   } //map中的find方法,傳入一個閉包參數,可以查找map中第一個滿足條件的一個Entry(鍵值對實體)

   println(v.key);

   map.each {

     println(it.getKey()+":"+it.getValue());

   } //可以使用map的each方法,參數是一個閉包,來遍歷map

   map還有一些其他方法,所以這里可不一一列舉了

   def resMap=map.sort {

      e1,e2->

        return e1.key==e2.key?0:e1.key>e2.key?1:-1

  } //map的sort方法傳入一個閉包參數,對map進行排序,返回的是一個排序后的新的map,注意原map并沒有變化

Range (范圍)
rang相當于一個輕量級的List

def rang=1..10 //這里相當于定義了一個集合,集合中的元素值從1到10

   println(range.class); //groovy.lang.IntRange

   println(rang[0]) //range[0]為1 

   println(range.getFrom());// 1 range.getFrom() 獲取range的下限值

   println(range.getTo()); //10 range.getTo()獲取range的上限值

   //如果定義的def range=10..1; range.getFrom()和range.getTo()的值還是1,10

   //因為10..1 下限值還是1,上限值還是10  

   def charRange='f'..'a';

   charRange.each {

     println(it)

   } //打印出 f,e,d,c,b,a

   def score=60;

   switch (score){
    case 0..59:
        println("及格");
        break
    case 60..85:
        println("及格");
        break
    case 86..100:
        println("優秀");
        break
}

(5)Groovy中的class(類)、inteface(接口)、trait

class

Groovy中的class(類)和Java中的class(類)是一樣的,唯一的區別在于
默認的類、成員、方法的訪問權限都是public的

interface

Groovy中的interface(接口)和Java中的interface(接口)是一樣的,區別可能還是Groovy中定義接口的時候,如果不寫訪問權限默認就是public的而Java中定義接口的時候,如果不寫訪問權限,默認不是public的,那么不同包下的類是無法訪問這個接口的;

trait

trait這個是Groovy中新加的類型,但是其實他就是一種介于抽象類和接口之間的類型;trait中可以定義抽象方法(即不實現),也可以定義正常方法; 使用的時候,和接口一樣,也是要implement的,非抽象類實現是需要實現其抽象方法

trait MyTrait{

      abstract void test();

      void play(){

         prinlt("play game");

      }

    }  

    class TestClass implement MyTrait{

       @Override 
       void test(){

       }

    }

三、自定義Gradle插件

自定義插件的方式:

1.獨立項目

一個獨立的Java項目/模塊,可以將文件包發布到倉庫(jcenter),使其他項目方便引用

2.Build script腳本

把插件寫在build.gradle文件中,一般用于簡單的邏輯,只在該build.gradle中可見

3.buildSrc目錄

將插件源碼放在buildSrc/src/main/groovy/中,只對該項目可見

我們這里以獨立的Java Library模塊自定義插件方式為例,來學習一下如何自定義一個Gradle插件;

每次發布APK之前,可能還需要對APK進行加固,所以也可以開發一個加固插件,來自動進行APK加固,我們這里以開發一個360加固插件為例;

我們知道如果是手動使用360加固,我們肯定是需要打開360加固的軟件,然后輸入用戶名,密碼登錄進軟件,然后選擇應用加固選項,上傳打包好的APK文件,就會自動進行加固,加固好之后,就會自定下載加固好的APK,然后我們還需要對加固好的APK文件進行簽名,簽名后的加固APK文件就可以正常安裝使用了;

Android自定義Gradle插件的實現、上傳和使用過程
Android自定義Gradle插件的實現、上傳和使用過程

Android自定義Gradle插件的實現、上傳和使用過程

如果我們是使用自定義插件的方式來自動完成360加固,那上面這些步驟,從登錄開始到上傳應用,到加固,到對加固后的應用進行簽名,都要以代碼的方式來實現;

(1)我們使用Android Studio來創建一個正常的Android項目,在Android項目中新建一個Java Library Module;

Java Library Module名字,這里我們取plugin

Module的build.gradle文件中引入groovy插件,dependencies中

引入gradle插件,以及gradleApi因為在編寫插件的時候,是要用到gradle相關的API的

plugins {  id 'groovy'  }   或者 apply plugin:'groovy'

dependencies {

    implementation 'com.android.tools.build:gradle:4.1.3'
    implementation gradleApi()
 
  }

(2) Android Studio 切換項目試圖為Project,然后修改plugin的src/main/java 這個java目錄名字為groovy

Android自定義Gradle插件的實現、上傳和使用過程

(3) 然后在src/main/groovy/…(包名)/下新建插件源碼文件

這里要新建File(注意這里必須要新建一個File,不是新建java ,class等),File文件的名字以.groovy后綴結尾

我們這里新建一個GiaGuTask.groovy 的File,然后在GiaGuTask.groovy中開始插件的開發:首先要先添加包名,由于 Android Stuido不能識別.groovy文件 所以不會給我們自動添加包名,所以需要我們自己添加包名;package com.example.plugin

這個Task中就是將上述的登錄360加固軟件,上傳APK,加固,簽名加固后的APK文件,全部用執行命令的方式來實現,360加固軟件包下的help.txt中實際上就提供了上 登錄360加固軟件,上傳APK,加固,簽名加固后的APK文件的命令行命令

Android自定義Gradle插件的實現、上傳和使用過程

Android自定義Gradle插件的實現、上傳和使用過程

所以我們的新建的Task如下:

package com.example.plugin

import com.android.builder.model.SigningConfig
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class GiaGuTask extends DefaultTask{


    GiaGuBean mGiaGuBean;

    SigningConfig signingConfig;

    File apkFile;

    GiaGuTask() {
        group="jiagu"
    }

    @TaskAction
    void run() {

        project.exec {

            it.commandLine(
                    "java",
                    "-jar",
                    mGiaGuBean.getJiaGuTools(),
                    "-login",
                    mGiaGuBean.getUserName(),
                    mGiaGuBean.getPassword(),

            );

        }

        if (signingConfig) {

            project.exec {

                it.commandLine(
                        "java",
                        "-jar",
                        mGiaGuBean.getJiaGuTools(),
                        "-importsign",
                        signingConfig.storeFile.absolutePath,
                        signingConfig.storePassword,
                        signingConfig.keyAlias,
                        signingConfig.keyPassword
                )

            }
        }

        project.exec {


            it.commandLine("java",

                    "-jar",

                    mGiaGuBean.getJiaGuTools(),

                    "-jiagu",

                    apkFile.absolutePath,

                    apkFile.parent,

                    "-autosign"

            )

        }


    }

}

當然這里的GiaGuTask使用到了一個GiaGuBean,這個GiaGuBean里面定義了一些我們需要到時候在build.gradle
設置的配置信息,登錄的用戶名,密碼,加固工具所在的位置(加固工具就是360加固軟件包下的jiagu.jar文件)

Android自定義Gradle插件的實現、上傳和使用過程

這些需要從build.gradle中設置的配置信息,我們需要在GiaGuBean這個實體類中定義,并且定義set,get方法

package com.example.plugin

class GiaGuBean {

    String userName;
    String password;
    String jiaGuTools

    String getUserName() {
        return userName
    }

    void setUserName(String userName) {
        this.userName = userName
    }

    String getPassword() {
        return password
    }

    void setPassword(String password) {
        this.password = password
    }

    String getJiaGuTools() {
        return jiaGuTools
    }

    void setJiaGuTools(String jiaGuTools) {
        this.jiaGuTools = jiaGuTools
    }

}

然后新建一個GiaGuPlugin.groovy 的File,然后定義一個class GiaGuPlugin 需要實現 DefaultPlugin
并且實現apply方法,在apply方法中進行相應的實現,并且創建一個或者多個Task的,因為最終的插件功能,都是一個個Task的執行

package com.example.plugin

import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
import com.android.build.gradle.api.BaseVariantOutput
import com.android.builder.model.SigningConfig
import org.gradle.api.Plugin
import org.gradle.api.Project

class GiaGuPlugin implements Plugin<Project>{

    @Override
    void apply(Project project) {
        GiaGuBean giaGuBean = project.extensions.create("jiagu", GiaGuBean.class);

        project.afterEvaluate {

            AppExtension appExtension = project.extensions.android;

            appExtension.applicationVariants.all {
                    //debug/release

                ApplicationVariant variant ->

                    //對應變體(debug/release)的簽名配置
                    SigningConfig signingConfig = variant.signingConfig;

                    variant.outputs.all {

                        BaseVariantOutput baseVariantOutput ->

                            //輸出的APK文件
                            File apkFile = baseVariantOutput.outputFile;

                            //創建加固任務
                            GiaGuTask giaGuTask = project.tasks.create("jiagu${variant.baseName.capitalize()}", GiaGuTask.class);
                            giaGuTask.mGiaGuBean = giaGuBean;
                            giaGuTask.signingConfig = signingConfig;
                            giaGuTask.apkFile =apkFile;

                    }
            }


        }

(4)插件的配置

插件開發好了之后,就需要進行配置,plugin Module的src/main目錄下新建一個resources目錄,再在resources目錄下新建一個META-INF目錄,再在META-INF目錄下新建一個gradle-plugins目錄; 然后在gradle-plugins目錄下新建一個以 .properties后綴的文件,這個文件的名字就是到時候我們在引用插件時的名字我們這里取名:com.example.plugin.properties;這個文件里面我們需要配置插件的實現類

  implementation-class=com.example.plugin.GiaGuPlugin

到時候我們引用插件的時候就使用com.example.plugin這個名字;

Android自定義Gradle插件的實現、上傳和使用過程

(5)打包插件上傳倉庫

我們這里是打包插件上傳Maven本地倉庫,需要依賴maven-plugin插件,所以在plugin這個Java Library Module的build.gradle中添加maven-plugin插件的使用

apply plugin:'maven-publish'

publishing{

            publications{

            Jiagu(MavenPublication){ //Jiagu 這個名字隨意取

            from components.java  //這個表示要把源碼生成的jar包上傳

            groupId 'com.example' //配置插件的groupId(分組ID)

            artifactId "plugin"   //配置ID

            version "1.0" //配置版本號
        }

     }
     
   }

groupId、artifactId、version這三個配置構成了到時候我們依賴插件的時候的寫法: groupId:artifactId:version,我
們到時候依賴這個plugin插件的時候,應該是在Android項目的Project的build.gradle的dependencies中添加依賴:classpath “com.example:plugin:1.0”
引用maven-publish插件之后,build(編譯) plugin module之后,我們就可以在gradle窗口中查看到plugin下Tasks下會有publishing的Task,點開publishing這個Task下,我們點擊publishToMavenLocal(打包上傳插件到本地的maven庫),操作成功過后,在C:\Users\Administrator\下回有一個.m2目錄,這個目錄的repository目錄下會有 com\example\plugin這個目錄所以是1.0(version)目錄下就會有對應的插件plugin-1.0.jar,和兩個插件信息文件:plugin-1.0.module、plugin-1.0.pom;

Android自定義Gradle插件的實現、上傳和使用過程

Android自定義Gradle插件的實現、上傳和使用過程
(5)使用插件

添加插件的依賴
我們在Android項目中的Project的build.gradle中添加插件依賴 由于我們使用的是本地maven庫中的插件,所以repositories中需要添加mavenLocal()倉庫

repositories {

           ...
           
           mavenLocal()

         }                         

      dependencies {
        ...
        classpath "com.example:plugin:1.0" 

        //就是之前上傳的是偶配置groupId:artifactId:version

      }

引用插件

在Android項目主module(一般為app)的build.gradle中引用插件

apply plugins:'com.example.plugin' //就是開發插件的時候resources/META-INF/gradle-plugins/com.example.plugin.properties 這個文件的名字

或者現在都是這種寫法,在plugins{}下添加插件ID

plugins {

      ...

      id 'com.example.plugin' 

      //就是開發插件的時候resources/META-INF/gradle-plugins/com.example.plugin.properties 這個文件的名字 

}

當然app主module中的build.gradle中還要配置之前在定義GiaGuBean中的登錄用戶名,密碼,加固工具位置信息

Android自定義Gradle插件的實現、上傳和使用過程

執行插件任務

上述步驟之后,就會在gradle窗口中主module(app)的Tasks下會有一個jiagu任務,這個名字實際就是你開發插件的 時候,定義Task時候,為Task設置的groupId,如果沒有設置task的groupId,則插件的任務會在module(app)Tasks的other目錄下點擊jiagu下的操作,就會執行我們的加固任務;
當然我們要先確保APK文件已經存在,因為之前我們定義GiaGuPlugin.groovy時,里面APK文件使用的是baseVariantOutput.outputFile,也即build/outputs/apk/下release或者debug目錄下的APK,所以我們只要build一下就會生成APK文件,然后我們再點擊gradle窗口下,app/Tasks/jiagu下的加固任務即可進行加固

Android自定義Gradle插件的實現、上傳和使用過程

整個加固的過程,在run窗口下都會有日志打印

Android自定義Gradle插件的實現、上傳和使用過程
Android自定義Gradle插件的實現、上傳和使用過程

Android自定義Gradle插件的實現、上傳和使用過程

加固任務執行完畢之后build/outputs/apk/ 對用的目錄下就會生成加固簽名后的APK文件

Android自定義Gradle插件的實現、上傳和使用過程

以上就是一個自定義gradle插件的,實現、上傳、使用過程

“Android自定義Gradle插件的實現、上傳和使用過程”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

特克斯县| 丹阳市| 兰西县| 祁东县| 翁源县| 周宁县| 巍山| 施甸县| 丹阳市| 云浮市| 温泉县| 吉木乃县| 玉环县| 綦江县| 赤水市| 襄垣县| 铜陵市| 惠安县| 临桂县| 德格县| 循化| 三原县| 广汉市| 北流市| 永兴县| 铜梁县| 芜湖县| 甘德县| 嘉黎县| 临清市| 龙井市| 余干县| 拜城县| 福鼎市| 江安县| 和顺县| 聂拉木县| 新安县| 边坝县| 饶阳县| 宝山区|