使用 kotlin compiler plugin 实现,目前仅作用于 Kotlin 函数,为 Kotlin 函数提供代理实现。
Implemented using kotlin compiler plugin, currently only applicable to Kotlin functions, providing proxy implementation for Kotlin functions.
Kotlin | KSP | Sword | PluginId |
---|---|---|---|
1.9.21 | 1.9.21-1.0.15 | 0.0.4 | com.sunxiaodou.kotlin.sword.kcp |
1.8.22 | 1.8.22-1.0.11 | 0.0.3 | com.sunxiaodou.kotlin.sword.kcp |
1.7.10 | 1.7.10-1.0.6 | 0.0.2 | com.sunxiaodou.kotlin.sword.kcp |
plugins {
id("com.sunxiaodou.kotlin.sword.kcp") version "<latest-version>" apply false
// Option KSP
id("com.google.devtools.ksp") version "<ksp-version>" apply false
}
plugins {
id("com.sunxiaodou.kotlin.sword.kcp")
// Option KSP
id("com.google.devtools.ksp")
}
dependencies {
implementation("com.sunxiaodou.kotlin:sword-api-kt:<latest-version>")
// Option 为标记[InvocationHandler]的子类生成FqName索引类`HandlerFqNames`
ksp("com.sunxiaodou.kotlin:sword-compiler-ksp:<latest-version>")
}
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class Proxy(
/**
* 是否启用, 默认True
*/
val enable: Boolean = true,
/**
* [InvocationHandler]实现类的全限定名, 实现类必须有无参构造方法
*
* e.g. com.example.ProxyTestInvocationHandler
*/
val handler: String = "",
)
interface InvocationHandler {
fun invoke(className: String, methodName: String, args: Array<Any?>): Any?
}
/**
* 标记[InvocationHandler]的子类, 为其生成FqName索引类`HandlerFqNames`
*
* 使用 ksp 实现
*
* Created by guodongAndroid on 2022/8/17.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
annotation class ProxyHandler(
/**
* 生成字段的名称, 默认为类名
*
* `paramName`参数名称不要随意变动
*/
val paramName: String = ""
)
向 Proxy
注解中的 handler
参数注入 InvocationHandler
实现类的全限定名(Fully Qualified Name),其实现类必须有无参构造方法。
class Test {
@Proxy(
enable = BuildConfig.isDebug,
handler = HandlerFqNames.GET_TEXT_NO_ARG
)
fun getTextNoArg() = "guodongAndroid"
@Proxy(
enable = BuildConfig.isDebug,
handler = HandlerFqNames.GetTextArgInvocationHandler
)
fun getTextArg(
b: Byte,
z: Boolean,
c: Char,
s: Short,
i: Int,
l: Long,
f: Float,
d: Double,
str: String,
ia: IntArray,
sa: Array<String>,
ls: List<String>,
lls: List<List<String>>,
map: Map<String, String>,
user: User,
callback: Callback,
): User {
return User("guodongAndroid-Release", 28)
}
}
@ProxyHandler
class GetTextArgInvocationHandler : InvocationHandler {
private val TAG = GetTextArgInvocationHandler::class.java.simpleName
override fun invoke(className: String, methodName: String, args: Array<Any?>): Any? {
Log.e(TAG, "invoke: className = $className, methodName = $methodName, args(${args.size}) = ${args.joinToString()}")
return User("guodongAndroid-Debug", 18)
}
}
@ProxyHandler("GET_TEXT_NO_ARG")
class GetTextNoArgInvocationHandler : InvocationHandler {
private val TAG = GetTextNoArgInvocationHandler::class.java.simpleName
override fun invoke(className: String, methodName: String, args: Array<Any?>): Any? {
Log.e(TAG, "invoke: className = $className, methodName = $methodName, args(${args.size}) = ${args.joinToString()}")
return "guodongAndroid-Debug"
}
}
// The file is automatic generated by Sword, don't modify it.
package com.guodong.android.sword.app
import kotlin.String
/**
* The class is automatic generated by Sword, don't modify it.
*
* [com.guodong.android.sword.api.kt.InvocationHandler]实现类的全限定名
*/
public object HandlerFqNames {
/**
* [com.guodong.android.sword.app.GetTextArgInvocationHandler]
*/
public const val GetTextArgInvocationHandler: String =
"com.guodong.android.sword.app.GetTextArgInvocationHandler"
/**
* [com.guodong.android.sword.app.GetTextNoArgInvocationHandler]
*/
public const val GET_TEXT_NO_ARG: String =
"com.guodong.android.sword.app.GetTextNoArgInvocationHandler"
}