注解
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class BindView(val resId: String)
注解处理器
//需要注册,
class BindViewProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
environment.logger.warn("=== BindViewProcessorProvider 被调用,创建处理器实例 ===")
return BindViewProcessor(environment)
}
}
class BindViewProcessor(val environment: SymbolProcessorEnvironment) : SymbolProcessor {
private val codeGenerator = environment.codeGenerator
private val logger = environment.logger
override fun process(resolver: Resolver): List<KSAnnotated> {
logger.warn("BindViewProcessor")
//获取注解
val annotationFields = resolver.getSymbolsWithAnnotation("com.example.annotations.BindView")
.filterIsInstance<KSPropertyDeclaration>()
val fieldsByClass = annotationFields.groupBy { it.parent as KSClassDeclaration }
fieldsByClass.forEach { (ksClass, fields) ->
generateBinding(ksClass, fields)
}
return emptyList()
}
fun generateBinding(ksClass: KSClassDeclaration, fields: List<KSPropertyDeclaration>) {
//获取类名和包名
val packageName = ksClass.packageName.asString()
val className = ksClass.simpleName.asString()
val bindingClassName = "${className}_viewBinging"
val bindings = fields.map {
logger.warn("------${it.annotations.first().annotationType}")
val fieldName = it.simpleName.asString()
val viewId = it.annotations.filter { it.annotationType.toString() == "BindView" }
.first().arguments.first().value as String
logger.warn("viewId: $viewId")
val fieldType =
it.type.resolve().declaration.qualifiedName?.asString() ?: error("无法解析类型")
Binding(fieldName, viewId, fieldType)
}
val code = """
package $packageName
class $bindingClassName{
companion object {
fun binding(activity:$className){
${bindings.joinToString("\n") { "activity.${it.fieldName} = activity.findViewById(${it.viewId}) as ${it.fieldType}" }}
}
}
}
""".trimIndent()
logger.warn("生成的代码:\n $code")
codeGenerator.createNewFile(
dependencies = Dependencies(false, ksClass.containingFile!!),
packageName = packageName, fileName = bindingClassName, extensionName = "kt"
).bufferedWriter().use { it.write(code) }
logger.warn("生成View绑定类: $packageName.$bindingClassName")
}
//创建一个辅助类,用于存储字段绑定信息
private data class Binding(val fieldName: String, val viewId: String, val fieldType: String)
}
注册方式
main -> resources ->META-INF->Services->com.google.devtools.ksp.processing.SymbolProcessorProvider
文件内容:
com.example.annotation_processor.BindViewProcessorProvider
module processor的 gradle文件
// KSP 符号处理API(必须)
implementation("com.google.devtools.ksp:symbol-processing-api:1.9.0-1.0.13")
// 代码生成工具(可选,如JavaPoet)
implementation("com.squareup:javapoet:1.13.0")
implementation(project(":annotations"))
project 的 gradle文件
plugins {
id("com.google.devtools.ksp") version "2.0.21-1.0.27" apply false
}
App的gradle文件
dependencies {
ksp(project(":annotation-processor"))
implementation(project(":annotations"))
}