发现
最近在读leakcanary源码时,发现其中有一个比较巧妙的使用by noOpDelegate(),具体代码如下:
class ActivityWatcher(
private val application: Application,
private val reachabilityWatcher: ReachabilityWatcher
) : InstallableWatcher {
private val lifecycleCallbacks =
object : Application.ActivityLifecycleCallbacks by noOpDelegate() {
override fun onActivityDestroyed(activity: Activity) {
reachabilityWatcher.expectWeaklyReachable(
activity, "${activity::class.java.name} received Activity#onDestroy() callback"
)
}
}
}
从代码中可以发现,在实现ActivityLifecycleCallbacks对象表达式时,只实现了onActivityDestroyed(activity: Activity),这是为什么呢?
分析
带着疑问,就去看了noOpDelegate():
internal inline fun <reified T : Any> noOpDelegate(): T = leakcanary.internal.noOpDelegate()
internal inline fun <reified T : Any> noOpDelegate(): T {
val javaClass = T::class.java
return Proxy.newProxyInstance(
javaClass.classLoader, arrayOf(javaClass), NO_OP_HANDLER
) as T
}
private val NO_OP_HANDLER = InvocationHandler { _, _, _ ->
// no op
}
就可以发现noOpDelegate()返回的是T的动态代理,代理的方法均是空实现。
而leakcanary巧妙的结合了动态代理和kolin中的接口委托,即object : Application.ActivityLifecycleCallback实现了方法onActivityDestroyed(),其他的方法委托给noDelegate()实现; 使用这样的方式,只需要实现想要实现的方法即可,这样就不用重写接口的每一个方法。
扩展
这样的使用可以用到接口Application.ActivityLifecycleCallbacks、Animator.AnimatorListener。