AOP Observable

在公司重构的过程中,希望用KVO的方式传递数据变化的事件。然而,在传统Android的写法中,Bean是没有setter的,就没有时机来notifyObservers了。
值得庆幸的是AspectJ能够切入Field access事件,用AOP就是一个非常好的解决方法了。项目,使用方法见README.md,这里只说原理。跪谢大神的Hugo插件

切入

非常基础的AspectJ,就是我这种半吊子写的PointCut和Advice。主要思路就是切入所有:

  • Observable子类中
  • 没有被标记为IgnoreField的field
  • 在被没有标记IgnoreInovker的类或方法中
  • 被修改的代码

分发

上面的切入有个大bug,对同一个对象的连续修改会触发多次无用的notifyObservers。为了解决这个问题,采用两个方法:

  • 对于有Looper的线程,所有行为都是以代码段(Message)的方式放置到queue中串行执行的,那么可以将一个代码段(Message)中的所有修改集中去重,并在queue的下一个Message统一分发。这个方法无感的解决掉了大部分(因为主线程是LooperThread)修改的去重
  • 对于非Looper线程,需要给修改的方法标记为IgnoreInvoker,并在修改完成后手动调用Dispatchers#notifyDataChanged。这个并不优雅,但是我并没有找到AspectJ这么复杂的PointCut声明方式。目测可以用反射和JointPoint中的内容解决问题,但是对于尽可能轻量化的切面会过重

猜你喜欢

转载自blog.csdn.net/pouloghost/article/details/78499943
AOP