安卓Gradle插件开发-ASM字节码修改-AutoRegist
今天需要开发一个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我发现我们遗漏了一个步骤
就是需要新建一个配置信息 我们现在来做
整个目录路径名称一定不能出错
我们在执行一次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
加一下这个插件
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