声明注解
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class BestAPI(val serviceId: String)
标注到方法上
@BestAPI(FUNCID_CMD_DEVICE_FIRMWARE_UPGRADE)
fun onUpgradeCmd(bestResult: BestResult) {
Log.d(TAG, "onUpgradeCmd: 收到升级命令")
//收到升级命令
upgradeManager.onUpgradeCmd(bestResult, true) { hasNew ->
//比对之后,确实要升级
Log.d(TAG, "onUpgradeCmd: 是否有要升级的版本$hasNew")
}
}
添加解析和业务逻辑
标记所有带有标记的方法
如下,我们标记了两个方法 updateErrorLog
和 updateErrorMsg
,对应的 serviceId 分别是 ,FUNCID_ZEUS_SUPT_FILELOG_UPLOAD
,FUNCID_ZEUS_SUPT_ERRMS
G_UPLOAD,
class ZeusReporter constructor(
context: Context,
) {
fun init() {
BestApiLoaderHelper.loadMethodsIn(this, SID_MAPPER)
}
fun onMessageReceived(bestResult: BestResult) {
Log.d(TAG, "收到消息 $bestResult")
val invoke = BestApiLoaderHelper.notifyBestApiMethod(
this,
SID_MAPPER,
bestResult
)
Log.d(TAG, "是否由ZeusReporter处理 $invoke")
}
@BestAPI(FuncIdConstantBasic.FUNCID_ZEUS_SUPT_FILELOG_UPLOAD)
fun updateErrorLog(bestResult: BestResult) {
Log.d(TAG, "updateErrorLog $bestResult")
}
@BestAPI(FuncIdConstantBasic.FUNCID_ZEUS_SUPT_ERRMSG_UPLOAD)
fun updateErrorMsg(bestResult: BestResult) {
Log.d(TAG, "updateErrorMsg $bestResult")
}
fun release() {
SID_MAPPER.clear()
cancel()
}
}
加载含有注解的方法
在类实例初始化的时候,通过 BestApiLoaderHelper.loadMethodsIn(this, SID_MAPPER)
将含有标签的方法进行加载到 val SID_MAPPER = mutableMapOf<String, Method>()
具体如下:
fun loadMethodsIn(any: Any, mutableMap: MutableMap<String, Method>) {
mutableMap.clear()
val methods = any.javaClass.declaredMethods
for (method in methods) {
val annotation = method.getAnnotation(BestAPI::class.java)
if (annotation != null) {
mutableMap[annotation.serviceId] = method
Log.d(TAG, "add method ${annotation.serviceId}")
}
}
}
添加业务逻辑,invoke对应方法
例如,在 onMessageReceived
收到消息的时候,根据消息的 serviceid 调用对应的标注了相应serviceid的方法,
val invoke = BestApiLoaderHelper.notifyBestApiMethod(
this,
SID_MAPPER,
bestResult
)
具体就是通过前面加载注册的方法,找到对应的method进行invoke
fun notifyBestApiMethod(
any: Any,
mutableMap: MutableMap<String, Method>,
bestResult: BestResult,
): Boolean {
val method = mutableMap[bestResult.funcId()]
method?.let {
try {
it.invoke(any, bestResult)
return true
} catch (ex: InvocationTargetException) {
ex.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
}
return false
}
以上就是通过注解标注方法,从而进行业务分发,减少出现通过 serviceid来判断具体调用方法的 if else 模式的代码
if(serviceid=="xxx"){
dosomething1()
}else if(serviceid="xxxx"){
donsomething2()
}else if ....
如果 if else 多了,注解的优势就体现出来的