前言
动态代理是一种在编程中设计模式,允许你在运行时创建一个代理对象来替代原始对象,以便在方法调用前后执行额外的逻辑。Android中动态代理使用场景,如:性能监控、AOP和事件处理、权限检查、日志记录。
什么是动态代理
代理对象通常实现与原始对象相同的接口,可以添加自定义的行为。动态代理在运行时生成,不需要在编译时知道原始对象的类型。
原理
- InvocationHandler(调用处理器):接口,由开发人员实现。包含方法
invoke在代理对象上的方法被调用时会被调用。在invoke方法内,可以自定义方法调用前后执行的逻辑。 - Proxy(代理类):Java提供的类,用于创建代理对象。需要传递
ClassLoader、一组接口以及一个InvocationHander给Proxy.newProxyInstance方法,然后生成代理对象。
interface MyInterface{
fun doSomething()
}
class MyImplementation :MyInterface{
override fun doSomething() {
println("MyImplementation doSomething call")
}
}
class MyInvocationHandler(private val realObject:MyInterface):InvocationHandler{
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
println("MyInvocationHandler invoke before call")
val result = method?.invoke(realObject,*(args?: emptyArray()))
println("MyInvocationHandler invoke after call")
return result
}
}
fun main() {
val realObject = MyImplementation()
val proxyObject = Proxy.newProxyInstance(
MyInterface::class.java.classLoader,
arrayOf(MyInterface::class.java),
MyInvocationHandler(realObject)) as MyInterface
proxyObject.doSomething()
}
输出:
MyInvocationHandler invoke before call
MyImplementation doSomething call
MyInvocationHandler invoke after call
MyInvocationHander拦截了doSomething方法调用,在方法前后添加了额外的逻辑
性能监控
class MyInvocationHandler(private val realObject:MyInterface):InvocationHandler{
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
val startTime = System.currentTimeMillis()
val result = method?.invoke(realObject,*(args?: emptyArray()))
val endTime = System.currentTimeMillis()
val duration = endTime - startTime
println("Performance ${method?.name} took $duration ms to execute")
return result
}
}
输出:
Performance doSomething took 2 ms to execute
事件处理
class ClickHandlerProxy(private val target: View.OnClickListener) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
if (method?.name == "onClick") {
Log.d("ClickHandler", "Click event intercepted")
}
return method?.invoke(target, *args.orEmpty())
}
}
val originalClick = View.OnClickListener {
Log.d("ClickHandler", "originalClick")
}
val proxyObject = Proxy.newProxyInstance(
originalClick::class.java.classLoader,
originalClick::class.java.interfaces,
ClickHandlerProxy(originalClick)
) as View.OnClickListener
button.setOnclickListener(proxyObject)
输出:
Click event intercepted
originalClick
在原始点击事件处理逻辑前后执行自定义逻辑,无需修改原始的OnClickListener实现
总结
动态代理,在不修改原始对象情况下添加额外的行为。