Orca.so
未经允许禁止转载
一、迟来的更新
一年前的一篇文章 Androd开发:保存私密字符串到So库 - 掘金 (juejin.cn) 这个虽然没什么人用,但是基于项目已在正式项目上使用,加上Android Build Gradle 7.0+ 部分改动,为了适配后续的版本,我还是决定更一下新功能。
二、Gradle 7.0+变动对我们的影响
1、BaseVariant过时了
以前我们Task任务等属性都需要在gralde的afterEvaluate方法执行之后才能获取到很多安卓对应的属性 现在我们可以换到下列这个方法下获取,例如区分debug或者release
project.extensions.getByType(AndroidComponentsExtension::class.java).onVariants {}
2、registerJavaGenerateTask这个任务没了,然后新的方法不太灵活
其实我们可以在这里找到接近的新方法:
gradle-recipes/build.gradle.kts at agp-7.3 · android/gradle-recipes (github.com)
但是基于操作灵活我们就自己写Task吧,其实就是生成好JAVA的代码然后把路径添加到SourceSet即可
project.extensions.getByType(AndroidComponentsExtension::class.java)
.apply {
beforeVariants {
android.sourceSets{
val outputDir = File(project.buildDir, "/generated/source/orca/${it.name}")
findByName(it.name)?.apply {
println("add sourceSet path = $outputDir")
java.srcDir(outputDir)
kotlin.srcDir(outputDir)
}
}
}
onVariants {
//创建别的任务
}
}
3、涉及到NDK编译时候 generateJsonModel 需要改为 configureCMake
通过编译其实不难发现generateJsonModel不再被使用,而是采用了configureCMake针对arm架构的分类Task 此处详细不展开,有兴趣的同学可以留言。
configureCMake [task ':app:configureCMakeDebug', task ':app:configureCMakeDebug[arm64-v8a]']
三、通过ASM修改字节码,完成通过注解变量然后反射注入对应加密的字符串内容。
有意思的是现在新的修改方式比以前通俗好理解,注册Transform方法也变了。
project.extensions.getByType(AndroidComponentsExtension::class.java).apply {
this.onVariants { variant ->
projectName = project.name
variant.instrumentation.transformClassesWith(
ClassVisitorFactory::class.java,
InstrumentationScope.PROJECT
) {}
variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES)
}
}
四、新功能使用方法
:app or :library
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'Orca'
id 'Orca-compiler'
}
dependencies{
implementation("com.github.ShowMeThe.Orca:orca-annotation:2.3.6")
}
根目录下的 build.gradle 引入行插件
buildscript{
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
classpath("com.github.ShowMeThe.Orca:plugin:2.3.6")
classpath("com.github.ShowMeThe.Orca:orca-compiler:2.3.6")
}
}
在项目中只需要简单注解:
class AndroidViewModel(application: Application) : AndroidViewModel(application) {
@CoreDecryption("data")
private var data = ""
@CoreDecryption("base")
private var data2 = ""
fun getValue() = data
fun getValue2() = data2
}
执行对应的viewModel.getValue()即可
五、总结一下
其实这次版本的适配难度不算大,但是也花了点时间阅读文档,总之这些知识还是需要平时积累,上班工作基本上都是针对业务类型开发,偶尔花点时间学一下新内容,不能让自己被技术的抛弃啊。
同时本项目 是针对7.0+以上的AGP进,过低版会出现以下报错:
Unable to find method 'com.android.build.gradle.internal.dsl.DefaultConfig.externalNativeBuild(Lkotlin/jvm/functions/Function1;)V'
com.android.build.gradle.internal.dsl.DefaultConfig.externalNativeBuild(Lkotlin/jvm/functions/Function1;)V
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)