安卓AOP实战:APT打造极简路由

DomSummerli 3年前
   <h2>特点</h2>    <p>1、0个类0行代码(除了apt及生成的仅仅一个类的代码)</p>    <p>2、0反射0性能损耗,基于编译期间注解处理器</p>    <p>3、支持任何类型的参数传递,没有原生Intent的数据大小限制</p>    <p>4、支持页面元素共享的转场动画</p>    <h2>用法</h2>    <p>那么,既然敢说极简,到底有多简单呢,来看看用法:</p>    <p><img src="https://simg.open-open.com/show/0ccff46b4a5fd2771680d23932c69801.jpg"></p>    <p>目标Activity注解</p>    <p>1、@Router(C.USER_INFO)注解参数 USER_INFO = "userInfo"; 就是当前页面的actionName简称。</p>    <p>2、@Extra(C.HEAD_DATA)注解标注上个界面传进来的参数user信息,注解内的值就是取值时的key。</p>    <p>3、@SceneTransition(C.TRANSLATE_VIEW)注解标注上个界面传过来的共享元素转场动画的View。</p>    <p>除了这个注解 ,就没有其他任何代码了。</p>    <p>使用时,也就一句话:</p>    <p>TRouter.go(C.USER_INFO, new ExtraData(C.HEAD_DATA, SpUtil.getUser()).build(), im_face);</p>    <p>对于不传参的就更简单了:</p>    <p>TRouter.go(C.FEED_BACK);</p>    <p>再看看之前的写法:</p>    <p>ActivityCompat.startActivity(mContext, new Intent(mContext, UserActivity.class) .putExtra(C.HEAD_DATA, SpUtil.getUser()) , ActivityOptionsCompat.makeSceneTransitionAnimation( (Activity) mContext, im_face, C.TRANSLATE_VIEW).toBundle());</p>    <p>于是,这些代码都可以注释掉删掉啦:</p>    <p><img src="https://simg.open-open.com/show/222055b58bfd873681cada85fcc54544.jpg"></p>    <p>效果对比</p>    <p>当然,重构前的目标Activity里的初始化代码,也可以删掉啦:</p>    <p><img src="https://simg.open-open.com/show/046ddb9a9f449590520e40df296adbf2.jpg"></p>    <p>删掉重构前的目标Activity里的初始化代码</p>    <p>为什么删掉呢,因为,这些极具规律性的代码,不需要手写,全部由APT自动生成了。</p>    <h2>原理</h2>    <p>来看看我们的TRouter里自动生成的页面跳转:</p>    <p><img src="https://simg.open-open.com/show/b70b4c65c1c77b0a3c13bc1227207155.jpg"></p>    <p>TRouter</p>    <p>以及自动给目标Activity自动初始化传参和转场View的代码:</p>    <p><img src="https://simg.open-open.com/show/d4d28e4adc96b93692469fcd524eb98e.jpg"></p>    <p>自动初始化</p>    <p>整个TRouter的原理,就是让Apt帮我们写代码。</p>    <p>先根据注解整理出需要的信息:</p>    <p><img src="https://simg.open-open.com/show/6efb31f70ee4bcaebfbf5469653f6e4e.jpg"></p>    <p>RouterActivityModel</p>    <p>然后按照固定套路生成代码就可以了,例如:</p>    <p><img src="https://simg.open-open.com/show/124f583cc2948ca925ce9080fde9f7dd.jpg"></p>    <p>APT生成代码</p>    <p>具体代码请看RouterProcessor。因为逻辑并不复杂,为了保持简洁,没有像ButterKnife那样针对每个目标单独生成代理类,直接生成全局的静态方法即可,只需要保证初始化赋值目标是Public即可,而ButterKnife的代理类实在同一个包名下,则没有这样的要求,但是ButterKnife的代理类的获取需要用反射,两种实现方式各有利弊吧。</p>    <p>好了 ,2016年最后一趟车即将到站了,所有代码在项目 <a href="/misc/goto?guid=4959732819763655316" rel="nofollow,noindex">T-MVP</a> 。</p>    <p>题外,TMVP一直在不断推翻,不断优化,不断重写,感兴趣的可以关注我的github看到最新的进展。TMVP全家桶现有TRecyclerView、TRouter、OkBus等。</p>    <p>更新日志:</p>    <p>2016/12/30:使用Apt生成全局路由TRouter,更优雅的页面跳转,支持传递参数和共享view转场动画</p>    <p>2016/12/29:去掉BaseMultiVH新增VHSelector支持更完美的多ViewHolder</p>    <p>2016/12/28:使用Apt生成全局的ApiFactory替代所有的Model</p>    <p>2016/12/27:增加了BaseMultiVH扩展支持多类型的ViewHolder</p>    <p>2016/12/26:抽离CoreAdapterPresenter优化TRecyclerView</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/6ccfa7b50f0e</p>    <p> </p>