一个小问题
最近碰到一个有趣的情况,在做一个功能时,考虑到从零开始开发需要花费大量的时间和精力,所以选用了一个有 UI 的库,并在这个库的基础之上进行二次开发。于是在项目中引入了这个库,当然,当时已经有大部分功能开发完成了,所以 UI 有一部分在 app 这个主模块中,而一部分则依赖这个库。Android Studio 中 app 模块是可以依赖其他引入项目的库的,而库则不可以依赖 app 模块,那这就引发了一个问题:主要功能已经在 app 中开发完毕,比如用户信息模块,而这个 UI 库的一些 UI 更新和功能也需要当前的用户信息,这该怎么办呢?
仔细分析
首先弄清楚这个问题的本质,这个问题的本质上是模块依赖引发的问题
,仅仅是库依赖不了 app 模块的问题,所以不要用过于复杂的方法去解决,比如通过文件读写(sp文件)或者 socket 之类的。在刚开始时我第一个想到的是用 EventBus,但是想了想觉得不合适。EventBus 是一个事件发布订阅的模型,你可以想象一下这个情况:
- UI 库发送
请求用户信息事件
- app 模块订阅了
请求用户信息事件
- app 模块在收到请求后,发送
返回用户信息事件
- UI 库订阅了
返回用户信息事件
,收到事件后解析获取相应的信息
本来一来一回的操作,竟然需要四步操作,实在是有点麻烦,那有没有简单一些的方法呢?肯定是有的(废话,不然我也不会写这篇文章),再来分析一下该怎么实现:
- app 中引入了 UI 库,所以 app 中可以直接使用 UI 库中的代码
- 可以在 UI 库中定义一个用户接口,定义一系列自己所需要的用户信息的方法
- 在 app 模块中实现这个接口,这很容易理解,app 可以直接使用 UI 库中的代码,而且 app 模块中也可以很轻易的访问到所需要的用户信息(毕竟原有的功能就是在 app 中开发的)
- 做完上面几步,最后就是把 app 中的这个实现类注入到 UI 库中,这一步利用 Java 的多态来做到,这里放一下简单的代码
1 | interface UserInterface { |
在 UserProxy 中定义一个接口类型的属性,之后 app 调用这个注入方法,注入一个实现对象,整个流程就轻松愉快的完成了。
所有的实现代码(不包括视图代码 Kotlin 实现)
库的接口等代码:
1 | interface UserInterface { |
app 中注入以及接口实现(简单实现。。。非生产代码)
1 | class UserImpl : UserInterface { |
最后,稍微想了想,如果从刚开始就采用组件化来进行开发的话,也许就不会存在这个问题了,在组件化开发中,app 模块只是一个壳,其他的一个个模块既是单独可运行的 app 又是一个个库,只需要通过改变配置即可实现切换。不过这也是有空的时候再去折腾了,而且这种开发模式……暂时对我来说也没什么意义,项目也没大到那种程度,编译运行的速度也还可以,完全没到忍受不了的程度,而且我觉得这种模式可能更适合开发人员比较多的情况�