IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 编译优化探索2 Hack字节码 -> 正文阅读

[移动开发]Android 编译优化探索2 Hack字节码

前言

承接上文:
Android 编译优化探索

再最初的版本中需要编译kotlin才能实现Hack自定义增量,但是还一个任务同样也及其耗时org.gradle.api.tasks.compile.JavaCompile,但是此任务不在kotlin插件,难道我们又要自己编译java插件?就连鄙人导师都觉得编译kotlin插件很麻烦。于是乎最后决定采用动态修改字节码的方式实现。作者使用javassist作为字节码编辑器。

JavaCompile创建流程

android工程中JavaCompile的创建是由AGP插件创建,其核心创建核心流程如下

//TaskFactoryUtils.kt

fun <T : Task> TaskContainer.registerTask(
    creationAction: TaskCreationAction<T>,
    secondaryPreConfigAction: PreConfigAction? = null,
    secondaryAction: TaskConfigAction<in T>? = null,
    secondaryProviderCallback: TaskProviderCallback<T>? = null
): TaskProvider<T> {
    val actionWrapper = TaskAction(creationAction, secondaryPreConfigAction, secondaryAction, secondaryProviderCallback)
    //调用register注册一个task,第一个参数task名字,第二个参数task类型,第三参数注入构造参数
    //这里的creationAction是JavaCompileCreationAction
    //creationAction.name 任务名字根据变体变化 比如tiya变体就为compileTiyaDebugJavaWithJavac
    //creationAction.type返回的一个class类型:JavaCompile::class.java
    return this.register(creationAction.name, creationAction.type, actionWrapper)
        .also { provider ->
            actionWrapper.postRegisterHook(provider)
        }
}


我们最后看看这个

class JavaCompileCreationAction(
    private val variantScope: VariantScope,
    private val processAnnotationsTaskCreated: Boolean
) : TaskCreationAction<JavaCompile>() {
	//...略
	  override val name: String
        get() = variantScope.getTaskName("compile", "JavaWithJavac")

    override val type: Class<JavaCompile>
        get() = JavaCompile::class.java
	//...略
}

知道大致流程我就可以根据如下思想进行操作:

  1. JavaCompileCreationActiontype替换成自己的JavaCompile类即可
class JavaCompileCreationAction(
    private val variantScope: VariantScope,
    private val processAnnotationsTaskCreated: Boolean
) : TaskCreationAction<JavaCompile>() {
	//...略
	//替换为HackJavaCompile 
    override val type: Class<JavaCompile>
        get() = HackJavaCompile::class.java
	//...略
}
  1. 抢在gradle的默认的类加载器之前修改类并强行加载(双亲委托知识)

因次插件会在根工程之后直接启用。

  1. 处理父加载器引用子加载器的类问题
    这个问题也是比较头疼的一个地方,在起初使用jdbc那样委托当前线程的类加载器去加载,然后通过反射去调用子类函数,但是最后发现当前线程类加载器居然是一个较为顶层的类加载器。最后采用所有引用的类都交付顶层类加载器加载,并禁使用lambda表达式(编译器会创建一个新的类,并用子类加载器加载)。

在这里插入图片描述

最后解决办法
在这里插入图片描述
如以下伪代码
在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:19:17  更:2022-02-03 01:20:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:00:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码