思路 demo项目源码
上一篇我们学习了如何创建并搭建出一个编译时注解工程,但是仅仅这样是不够的,我们还得用起来。
如果仅仅是想用起来的话,很简单,上一篇中我们定义了2个注解类@Service和@Autowar
第一:给具体的实现类打上@Service
第二:定义一个打了@Service的接口类并给这个属性打上@Autowar
第三:调用注入方法HzcInject.inject(this)
这样就完成了注解工作,简单有木有,完全看不到他们的关系,完全解耦。
但是这样就够了吗?我们要有点追求,这样还不够优雅,试想一下,就算你把HzcInject.inject(this)放在baseActivity中而且这个baseActivity也是只在当前的项目中,那么你是不是得每个项目的baseActivity都要打上HzcInject.inject(this)呢?明显不优雅啊~!所以,我们需要有一个总线去自动HzcInject.inject(this)
试想一个场景 A(主工程)B,C,D(属于A主工程的模块工程),其中B是C,D的公共依赖库,C和D的baseActivity都在B中,这个时候你往B打上HzcInject.inject(this),你会发现,坑爹啊,不注入啊,为什么?因为负责注入的工程仅对自身工程起作用,不会对其他依赖工程起作用,懵逼了吧。那怎么办?这个时候我们需要借鉴spring了。
解决方案 我们可以创建一个单例代理类负责对A,B,C,D项目进行代理注入(很高大上的感觉有木有),这个代理类在app启动的时候就得获得并缓存了所有的项目和被打上@Service,@Autowar的类,由于B是所有项目的公共依赖库,所以现在只要给B的baseActivity打上了HzcInject.inject(this)那么就能解决上面说的尴尬问题,一步到位。
具体核心代码实现 这里仅贴出相关的核心代码,其他相关的代码我就不贴了,相信能看到这里的人水平也不会低,能构思出属于自己的风格,不过要注意的就是,采用这种模式要注意包冲突问题。
获得所有的项目,写在主工程的gradle中,同时定义一个变量获得这个结果
buildConfigField 'String', 'INCLUDE_PROJECTS', '"' + getIncludeProjects() + '"'
//返回所有引用的项目名称
def getIncludeProjects() {
def projects = ""
def regEx = '[`~!@#$.<>-]'
rootProject.childProjects.each { obj ->
projects += obj.key.replaceAll(regEx, '') + ","
}
return projects.substring(0, projects.length() - 1)
}
具体使用流程 【android studio 编译时注解(三) 打造注入框架】App启动的时候application获得INCLUDE_PROJECTS,并启用代理类进行缓存需要的信息,在任意项目中的activity定义一个被打上了@Service的实现类的接口类属性,并且给这个属性打上@Autoware,在baseActivity.onCreate中调用inject(this),这个inject方法将调用运行时注解的代码进行注入工作。