Android基于Gradle8.0的插件开发

一、Gradle8.0插件的使用方式

随着Gradle和Android Gradle Plugin的版本升级,以及Kotlin DSL的加入,Gradle的配置和使用方式发生了很大的变化。插件仓库和依赖仓库的配置从之前的根工程下的build.gradle文件移到了settings.gradle.kts文件中,插件的引入方式也从之前的classpath更改为插件Id。插件的使用也是在子模块中由apply方式变更为id方式。

1、老版本中的配置方式

根工程下的build.gradle配置:

buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}


app模块的build.gradle配置:

apply plugin: 'com.android.application'

2、新版本中的配置方式

settings.gradle.kts配置:

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}


根工程下的build.gradle.kts配置:

plugins {
    id("com.android.application") version "8.1.2" apply false //引入插件
    id("org.jetbrains.kotlin.android") version "1.8.10" apply false //引入插件
}

apply false:表示只是将插件引入,并不会自动应用插件到项目中(插件里的任务不会自动执行,只有手动调用里面的任务或者配置使用插件后任务才会执行),可以按需在模块中配置使用

app模块的build.gradle配置:

plugins {
    id("com.android.application") //使用插件
}

二、Gradle8.0插件的自定义流程

之前使用Groovy、Java 、 手动配置的方式演示了Gradle插件的整个自定义流程《自定义gradle插件》。本文使用java-gradle-plugin 和 Kotlin重新梳理下Gradle插件的自定义流程。

1、新建一个Module模块hui_plugin(选择Kotlin Library)

2、在hui_plugin模块的build.gradle.kts中引入“java-gradle-plugin” 和 “org.jetbrains.kotlin.jvm” 插件。“java-gradle-plugin”插件可以大大简化插件的开发流程,这个插件会自动将java-library、gradleApi()引入进来,提供gradlePlugin配置插件id、版本号等信息,取代resources中声明插件类,取代maven发布信息的配置。“org.jetbrains.kotlin.jvm”插件支持使用Kotlin编写插件,取代Groovy和Java

plugins {
    id("java-gradle-plugin") //会自动引入java-library、gradleApi()
    id("org.jetbrains.kotlin.jvm") //支持kotlin编写插件
}

3、开始编写自定义的Plugin类

class PageAnalysisPlugin : Plugin<Project> {

    override fun apply(target: Project) {
        println("Hello PageAnalysisPlugin")
    }
}

4、在hui_plugin模块的build.gradle.kts中配置插件

gradlePlugin {
    plugins {
        create("pagePlugin") {
            group = "com.znh.plugin"
            version = "1.0.0"
            id = "com.znh.plugin.page" //插件的唯一标识,使用插件的时候就是这个id
            implementationClass = "com.znh.plugin.page.PageAnalysisPlugin" //PageAnalysisPlugin的全类名 取代resources声明
        }
    }
}


5、添加maven-publish插件,配置本地仓库地址以便于发布到maven

plugins {
    id("java-gradle-plugin") //会自动引入java-library、gradleApi()
    id("org.jetbrains.kotlin.jvm") //支持kotlin编写插件
    id("maven-publish") //发布到maven
}

publishing {
    repositories {
        maven {
            url = uri("../custom_plugin_repo") //本地maven地址
        }
    }
}


6、发布到maven仓库

7、生成本地maven仓库,至此,一个自定义插件的开发和发布就都完成了,相比于老的插件开发方式流程简化了很多

8、插件的使用需要先配置本地maven仓库,在settings.gradle.kts中配置本地仓库地址

pluginManagement {
    repositories {
        maven {
            url = uri("./custom_plugin_repo")
        }
    }
}


9、在工程根目录下的build.gradle.kts引入插件

plugins {
    id("com.znh.plugin.page") version "1.0.0" apply false
}

10、在app下的build.gradle.kts中使用插件

plugins {
    id("com.znh.plugin.page")
}

11、输出打印结果

三、Transform的替代方案

根据官方文档《Android Gradle 插件 API 更新》可知,Transform在7.2版本中被标记为废弃,在AGP8.0中被移除,但是并没有提供直接替代它的单一API,而是提供了几种场景的解决方案(转换字节码、向应用添加生成的类、基于整个程序分析的转换)。

像方法耗时统计、页面打点统计这类只需要在遍历中直接修改对应的class即可,不涉及到复杂的逻辑,可以使用转换字节码的方案进行实现。转换字节码的实现需要用到Instrumentation API,使用此API,每个类的插桩修改都是独立运行的,可以并行执行,效率较高。

之前基于Transform实现过一个模拟页面打点统计的Demo《ASM和自定义Transform的应用实践》,本文还以模拟页面打点统计为例,结合Instrumentation的transformClassesWith和AsmClassVisitorFactory来实现对Class的插桩修改。对于较复杂的场景后续考虑以路由信息收集为例使用“基于整个程序分析的转换”方案进行实现。

1、在hui_plugin模块的build.gradle.kts中引入android依赖

dependencies {
    implementation("com.android.tools.build:gradle:8.1.2")
}

2、定义一个AsmClassVisitorFactory类,然后实现其createClassVisitor方法和isInstrumentable方法,createClassVisitor方法中对class进行ASM修改操作,isInstrumentable方法定义需要修改的class的过滤条件。PageClassVisitor具体对Class的ASM操作跟之前一样,这里就不粘贴代码了,有兴趣的可以直接查看Demo代码。(ASM的字节码操作可以先用kotlin编写,然后使用AS工具转换成字节码。也可以结合ChatGPT,AI对这种标准化程度较高的功能比较擅长)

abstract class PageClassVisitorFactory : AsmClassVisitorFactory<InstrumentationParameters.None> {

    override fun createClassVisitor(classContext: ClassContext, nextClassVisitor: ClassVisitor): ClassVisitor {
        return PageClassVisitor(nextClassVisitor)
    }

    override fun isInstrumentable(classData: ClassData): Boolean {
        return classData.superClasses.contains("android.support.v7.app.AppCompatActivity")
                || classData.superClasses.contains("androidx.appcompat.app.AppCompatActivity")
                || classData.superClasses.contains("androidx.activity.ComponentActivity")
    }
}


3、在apply中通过Instrumentation进行遍历修改class

override fun apply(target: Project) {
    println("Hello PageAnalysisPlugin")
    val androidComponents = target.extensions.getByType(AndroidComponentsExtension::class.java)
    androidComponents.onVariants { variant ->
        variant.instrumentation.transformClassesWith(
            PageClassVisitorFactory::class.java, InstrumentationScope.ALL
        ) {}
        variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES)
    }
}

4、输出打印结果

Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/MainActivity--->onCreate
Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/FirstActivity--->onCreate
Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/SecondActivity--->onCreate
Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/SecondActivity--->onDestroy
Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/FirstActivity--->onDestroy
Page_TAG    com.znh.gradle80.plugin.demo         I  com/znh/gradle80/plugin/demo/MainActivity--->onDestroy

Demo地址:
https://github.com/huihuigithub/blog_demo_projects(gradle80-plugin-demo)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android Studio中配置Gradle 8.0,你需要进行以下步骤: 1. 在build.gradle文件中添加以下配置: ``` buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } } } ``` 这将添加Gradle插件的仓库地址。 2. 在settings.gradle文件中修改为以下配置: ``` pluginManagement { repositories { mavenLocal() maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/spring-plugin' } maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } gradlePluginPortal() mavenCentral() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenLocal() mavenCentral() maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } } } ``` 这将配置Gradle插件的管理和依赖解析。 请注意,以上配置中的URL是阿里云的仓库地址,你也可以根据需要修改为其他适合你的仓库地址。同时,这些配置也可以根据你的项目需求进行调整。 参考资料: \[1\] 链接:https://www.jianshu.com/p/42b2bd27b72c #### 引用[.reference_title] - *1* *2* [Android Studio gradle 8.0 版本安装出现 Read Timed Out](https://blog.csdn.net/qq_34438486/article/details/130906478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [离线安装android studio之---离线配置gradle(附gradle下载地址)](https://blog.csdn.net/Crystal_xing/article/details/108281846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值