安卓Gradle插件开发-ASM字节码修改-AutoRegist

2020-07-10  本文已影响0人  呵呵_9e25

今天需要开发一个Gradle插件然后完成基本调试

我们需要完成一些基本配置 比如gradle

大家可以复制我的这一份
首先是project的buildgradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        maven{ url rootProject.file("repo-local") }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.0"
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
        classpath 'com.billy.android:autoregister:1.4.2-SNAPSHOT'
//        classpath 'com.billy.android:autoregister:1.4.2'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

注意点
//需要关注这里 这里指向的是本地的repo-local目录 这个后面会说
maven{ url rootProject.file("repo-local") }

然后是app的buildgradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "com.example.testplugin"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}

这里可以基本不变

然后就是需要增加一个module作为我们的插件目录
我这里选择了AndoridLibrary
这里报了个错 其实是我们project的gradle有一个地方暂时没有资源
//就是这个 我们暂时要注释他 等我们写插件之后就可以用了
// classpath 'com.billy.android:autoregister:1.4.2-SNAPSHOT'

让项目自己同步一下 我们去做准备工作

1.删除多余目录
2.建立groovy目录
3.我们建立一个Plugin插件的基本文件必须是groovy文件
4.我们忘了一部 需要配置一下插件的buildgradle 我们直接去AutoRegister复制一份

apply plugin: 'groovy'
apply plugin: 'maven'

apply plugin: 'com.jfrog.bintray'

compileGroovy {
    sourceCompatibility = 1.7
    targetCompatibility = 1.7
    options.encoding = "UTF-8"
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}

repositories {
    mavenCentral()
}
dependencies {
    implementation 'com.android.tools.build:gradle:3.5.2'
}


//加载本地maven私服配置(在工程根目录中的local.properties文件中进行配置)
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def artifactory_user = properties.getProperty("artifactory_user")
def artifactory_password = properties.getProperty("artifactory_password")
def artifactory_contextUrl = properties.getProperty("artifactory_contextUrl")
def artifactory_snapshot_repoKey = properties.getProperty("artifactory_snapshot_repoKey")
def artifactory_release_repoKey = properties.getProperty("artifactory_release_repoKey")

def maven_type_snapshot = true
// 项目引用的版本号,比如implementation 'com.yanzhenjie:andserver:1.0.1'中的1.0.1就是这里配置的。
def artifact_version='1.4.2'
// 唯一包名,比如implementation 'com.yanzhenjie:andserver:1.0.1'中的com.yanzhenjie就是这里配置的。
def artifact_group = 'com.billy.android'
def artifact_id = 'autoregister'
group = artifact_group
version = artifact_version
def debug_flag = true //true: 发布到本地maven仓库, false: 发布到maven私服

task sourcesJar(type: Jar) {
    from project.file('src/main/groovy')
    classifier = 'sources'
}

artifacts {
    archives sourcesJar
}
uploadArchives {
    repositories {
        mavenDeployer {
            //deploy到maven仓库
            if (debug_flag) {
                repository(url: uri('../repo-local')) //deploy到本地仓库
            } else {//deploy到maven私服中
                def repoKey = maven_type_snapshot ? artifactory_snapshot_repoKey : artifactory_release_repoKey
                repository(url: "${artifactory_contextUrl}/${repoKey}") {
                    authentication(userName: artifactory_user, password: artifactory_password)
                }
            }

            pom.groupId = artifact_group
            pom.artifactId = artifact_id
            pom.version = artifact_version + (maven_type_snapshot ? '-SNAPSHOT' : '')

            pom.project {
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
            }
        }
    }
}


// 定义两个链接,下面会用到。
def siteUrl = 'https://github.com/luckybilly/AutoRegister' // 项目主页。
def gitUrl = 'git@github.com:luckybilly/AutoRegister.git' // Git仓库的url。

install {
    repositories.mavenInstaller {
        // 生成pom.xml和参数
        pom {
            project {
                packaging 'jar'
                // 项目描述,复制我的话,这里需要修改。
                name 'AutoRegister'// 可选,项目名称。
                description 'a gradle plugin project for android AOP.'// 可选,项目描述。
                url siteUrl // 项目主页,这里是引用上面定义好。

                // 软件开源协议,现在一般都是Apache License2.0吧,复制我的,这里不需要修改。
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }

                //填写开发者基本信息,复制我的,这里需要修改。
                developers {
                    developer {
                        id 'billy' // 开发者的id。
                        name 'billy' // 开发者名字。
                        email 'okkanan@hotmail.com' // 开发者邮箱。
                    }
                }

                // SCM,复制我的,这里不需要修改。
                scm {
                    connection gitUrl // Git仓库地址。
                    developerConnection gitUrl // Git仓库地址。
                    url siteUrl // 项目主页。
                }
            }
        }
    }
}

// 这里是读取Bintray相关的信息,我们上传项目到github上的时候会把gradle文件传上去,所以不要把帐号密码的信息直接写在这里,写在local.properties中,这里动态读取。
//Properties properties = new Properties()
//properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
    user = properties.getProperty("bintray.user") // Bintray的用户名。
    key = properties.getProperty("bintray.apikey") // Bintray刚才保存的ApiKey。

    configurations = ['archives']
    pkg {
        repo = "android"  // 上传到maven库。(这里要特别注意,如果写了maven报404错误,请在bintray创建一个仓库,这里填改成你创建的仓库的名字,如何创建请看下图。)
        name = "AutoRegister"  // 发布到Bintray上的项目名字,这里的名字不是implementation 'com.yanzhenjie:andserver:1.0.1'中的andserver。
        userOrg = properties.getProperty("bintray.userOrg") // Bintray的用户名,2016年11月更新。
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = ["Apache-2.0"]
        publish = true // 是否是公开项目。
    }
}

然后同步一下

我们大概看看这个配置


image.png image.png

这里定义了一个uploadArchives的Task 定义之后我们可以在gradle侧边栏找到他


image.png

具体作用就是上传这个插件,要么上传到本地要么上传到云端,我们这里是上传到本地
我们点击这个任务就会在这个repo-local生成一个插件库


image.png

好 这里暂时说道这

我们继续第一个插件开发

我们编辑完之后点击uploadArchives这个任务
看到BUILD SUCCESSFUL in 5s 这就是插件上传完成了

我们看一下本地这个repo-local

image.png

我发现我们遗漏了一个步骤
就是需要新建一个配置信息 我们现在来做

image.png

整个目录路径名称一定不能出错
我们在执行一次upload
我们看到已经生成了


image.png

但是有一个问题 就是为啥是com.billy那个因为我们buildgradle需要改 这个地方


image.png

这里我们为了方便可以不改 有兴趣的同学自己改 改了之后你引用就要注意了

其实就是project的buildgradle这里

    //如果改了刚刚插件的artifactgroup和id就要改这里
    classpath 'com.billy.android:autoregister:1.4.2-SNAPSHOT'

//
这里报了个错 我们调试一下

刚刚应该是这个路径问题
我们把module创建到app里面去了 所以大家也要注意这个路径
我们开始测试这个插件

翻车了 没事 我们找找原因

找到原因了 我们没有用它 找到app 的buildgradle
加一下这个插件

image.png

ok 插件生效

下一步就是调试了
我们试试吧

插件调试

刚刚编辑了一个remote调试器
现在随便找一个任务 加一下刚刚复制的这个

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

这里vmoptions的这个暂停要加y就是yes
suspend=y

然后切换到这个任务

image.png

它就会挂起等待


image.png

然后我们把刚刚新建的remote 也加调试


image.png

ok等待一会断点进来了

image.png

这里有个注意点要留意
就是如果构建过一次 就挂不上断点怎么办 简单的操作就是clean一下

我们先看看是不是会挂不上

我们先让断点过去了 执行完 我们在debug一下

这次幸运的进来了 因为我们还没到开发transform等我们到那一步再来看这个问题 现在就这样
今天finish

上一篇下一篇

猜你喜欢

热点阅读