上一篇我们有提到用 KAPT 参数去呼叫 纯 Kotlin 和 Android 的 code generator ,这篇要延续这个主题,继续来讲一下会怎麽样去呼叫它们来产生程序码。
我们在 annotation processor 里面有定义了 process
的方法:
@SupportedOptions("debug")
@AutoService(Processor::class)
class RssAnnotationProcessor : AbstractProcessor() {
// 略
override fun process(typeElementSet: MutableSet<out TypeElement>?, roundEnvironment: RoundEnvironment?): Boolean {
val logger = Logger(processingEnv.messager)
val isPureKotlinParser = processingEnv.options[KAPT_OPTION_KEY]?.toBoolean() ?: false
if (isPureKotlinParser) {
generateClassesForKotlin(logger, roundEnvironment)
} else {
generateClassesForAndroid(logger, roundEnvironment)
}
return true
}
// 略
}
其中的 generateClassesForKotlin
是产生 Kotlin 的 extension 和 parser 的地方。
private fun generateClassesForKotlin(logger: Logger, roundEnvironment: RoundEnvironment?) {
if (!isExtensionGenerated) {
KotlinExtensionGenerator(logger).generate().writeTo(processingEnv.filer)
isExtensionGenerated = true
}
generateParsers(roundEnvironment) { isRoot, element ->
logger.log("[RssAnnotationProcessor][generateClassesForKotlin] isRoot = $isRoot, element = $element")
KotlinParserGenerator(
element = element,
isRoot = isRoot,
logger = logger
).generate().writeTo(processingEnv.filer)
}
}
generateClassesForAndroid
则是负责产生 Android 的 extension 和 parser 。
private fun generateClassesForAndroid(logger: Logger, roundEnvironment: RoundEnvironment?) {
// This 'process' method could be called multiple times, so we use a flag to prevent it generate multiple times.
if (!isExtensionGenerated) {
AndroidExtensionGenerator(logger).generate().writeTo(processingEnv.filer)
isExtensionGenerated = true
}
generateParsers(roundEnvironment) { isRoot, element ->
AndroidParserGenerator(
element = element,
isRoot = isRoot,
logger = logger
).generate().writeTo(processingEnv.filer)
if (isRoot) {
AndroidReaderParserGenerator(
rootClassName = element.simpleName.toString(),
rootClassPackage = element.getPackage(),
logger
).generate().writeTo(processingEnv.filer)
}
}
}
因为 process
方法在 annotation processor 里面会被呼叫多次,每当有类别的 annotation 被扫到,就会被呼叫一次,每次都是不同的 generation cycle ,被产生的 class 也会被放在不同的档案里面。
Android 的部分比较特殊的地方是它有产生自己的 reader ,它跟 parser 的不同在於它是使用产生後的 parser 去做其他的处理,像是资料快取和取得网路的 RSS 档案来源,等於是把 parser 再包一层好用的 API ,这样在 Android 上面可以更简单地被使用。资料快取的部分,android 会用 database 以 url 当成是 key 去把资料存起来,也有设置过期时间,这样可以确保不会抓到过期的资讯,也让快取可以发挥作用。当然,外部 API 还是要按照自己的需求设计,也可以设计成让使用者可以决定要不要使用快取。在取得网路 RSS 来源的部分,是使用了 OkHttp 直接去取得档案内容。这些 Kotlin 和 Android 的 generator 会在後面的文章一一为各位讲解。
<<: D12 - 用 Swift 和公开资讯,打造投资理财的 Apps { 加权指数K线图分析 }
时间管力大师就是要忙里偷闲 各位应该知道 JavaScript 是单执行绪(单线程)的程序语言,也...
出现频率:极少数客户 (但是若有,该主机就会常常出现此讯息) 成因:目前未能完全确认原始成因,但是...
字串 string / 数字 number let userName: string; // 将变数...
今天要再来介绍一个我个人也蛮常使用的一布局 ConstaintLayout (约束布局) 承前两篇这...
今天心情蛮好的,期待叻2周终於等到这天了,生平第一次染发:) 这篇文有一半是我边染发变打出来的~ 染...