Suspend pointcut function
When you use @AndroidAopPointCut and @AndroidAopMatchClassMethod, if the entry function is modified by suspend, you have two choices of aspect processing classes
1. BasePointCut and MatchClassMethod that do not fully support suspend¶
When you choose the first option, AndroidAOP will treat it as a normal function, but remember that the return value cannot be modified. It can only return the result of joinPoint.proceed(), so this method cannot modify the return result, for example:
class MyAnnoCut3 : BasePointCut<MyAnno3> {
override fun invoke(joinPoint: ProceedJoinPoint, anno: MyAnno3): Any? {
Log.e("MyAnnoCut3", "====invoke=====")
return joinPoint.proceed()
}
}
Note
Although the return result cannot be modified, you can call joinPoint.proceed() instead, and you can also modify the input parameters, such as joinPoint.proceed(1,2)
2. BasePointCutSuspend and MatchClassMethodSuspend that support suspend¶
When you choose the second option, you need to specify the thread in invokeSuspend, such as using the withContext function, for example
class MyAnnoCut3 : BasePointCutSuspend<MyAnno3> {
override suspend fun invokeSuspend(joinPoint: ProceedJoinPointSuspend, anno: MyAnno3) {
withContext(Dispatchers.Main) {
...
joinPoint.proceed(object : OnSuspendReturnListener {
override fun onReturn(proceedReturn: ProceedReturn): Any? {
val result = proceedReturn.proceed()
Log.e(
"MyAnnoCut3",
"====onReturn=====${proceedReturn.returnType},result=$result"
)
return (result as Int) + 100
}
})
}
}
}
Note
- If you do not use the
withContextfunction, aClassCastExceptionexception may occur when the cut point function returns the result. The advantage of using this aspect processing class is that you can modify the return result (detailed introduction), and call other suspend functions - Try to use
joinPoint.proceedorjoinPoint.proceedIgnoreOtherin the last line of the withContext function
Warning
If the cut point function is not a suspend function, even if BasePointCutSuspend and MatchClassMethodSuspend are used, the invoke method will still be called back instead of the invokeSuspend method
In addition, for ordinary aspect processing classes, proceed() is not called and returns directly, for example:¶
class MyAnnoCut3 : BasePointCut<MyAnno3> {
override fun invoke(joinPoint: ProceedJoinPoint, anno: MyAnno3): Any? {
Log.e("MyAnnoCut3", "====invoke=====")
return null
}
}
class MyAnnoCut3 : BasePointCutSuspend<MyAnno3> {
override suspend fun invokeSuspend(joinPoint: ProceedJoinPointSuspend, anno: MyAnno3) {
withContext(Dispatchers.Main) {
...
joinPoint.proceedIgnoreOther(object : OnSuspendReturnListener2 {
override fun onReturn(proceedReturn: ProceedReturn2): Any? {
Log.e("MyAnnoCut3", "====invokeSuspend=====") return null
}
})
}
}
}