Android组件化之终极方案
Android组件化项目地址:Android组件化项目AndroidModulePattern
Fragment或View如何支持组件化
距离 Android组件化方案 发布已经半年有余,虽说这个方案已经能够解决一些项目的需求,但是依然不够完美。很多开发者也在博客和GitHub中留言甚至发邮件问我,Fragment怎么办? 目前市面上APP的风格还是类似于微信界面的比较多,好几个Fragment摆在主界面中,然后点击NavigationBar上的图标显示不同的Fragment。但是很显然Android组件化方案
并不适合这种情况。刚开始我给大家想了一个不是那么优雅的折中方案,这个方案是将我们应用的MainActivity移动到“app壳工程”中,因为“app壳工程”的本身就肩负着管理和组装业务组件的功能,因此这个MainActivity自然也就拿到了分散到其他业务组件中的Fragment,就像下图这样:
这个方案虽说也是可行的,但是显然没有达到我们期望的结果,我们理想的“app壳工程”是不应该跟业务有关的,他应该负责管理和组装其他组件,并将这些业务组件包装成一个可以发布到应用市场的APP,也就是说我们希望“app壳工程”不要和任何业务相关,不要耦合其他组件中的代码,我想我可以随意的替换那个空壳工程,而不会影响到我的APP打包,显然这个偷懒的方案是做不到这一点的。因此我必须解决的问题是:一个业务组件如何在不依赖其他业务组件的情况下拿到这些业务组件中的Fragment或者其他View?
假设小A收到一个邀请函,邀请他要去参加一个互联网技术会议,而这个会议在一个叫”XX大酒店“中举行,但是小A之前并没有听过这个酒店,那么他怎么才能找到这个酒店并参加会议呢?大多数同学都会习惯性的打开百度地图,然后输入“XX大酒店”,百度地图就会帮我找到这个酒店。但是大家有没有想过为什么百度地图能找到这个酒店呢?这时候肯定有人会说:这不是废话吗,百度地图都不知道还有谁知道?
这让我想起08年那时候还没有智能手机,我想去兰州的一个大厦,但是我问了周围很多路人都没有人知道这个大厦在哪里。而现在我们去一个地方从问路人变成了问百度地图,那么又回到哪句话,百度地图是怎么知道这些地方呢?有两种可能:一种是有人告诉百度地图某个地点在那里(那些小商店就是这样做的),另一种是百度地图派人去城市里晃悠把城市的所有显著的地标都记录下来。他们的关系就像下图表示的这样:
其实在 Android组件化方案
中已经有类似功能的组件:Common组件,还有另外一个就ARouter了。但是鉴于ARouter是开源库,我们不方便去修改,那么我们就在Common组件中做手脚。如果我想让Common组件知道D组件中的DFragment,我们需要怎么做呢?首先将CFragment和DFragment添加到Common组件中去,B组件想要获取DFragment,直接就去Common组件查找就行。
这时候你一定很激动,仿佛发现了什么绝世秘密一样,你恨不得立马就写个Demo测试下这个方案。当你撸起袖子开干后发现, What?
怎么才能把DFragment添加到BaseApplication啊?我们都知道Application启动后会回调onCreate()方法,貌似我们可以在Application启动的时候在onCreate方法中把Fragment添加到BaseApplication中去。这时候你脑海肯定会付出那个黑人问号的表情,总不能让D组件去依赖Common吧?这关系太特么乱了。
但是经过前面的铺垫,其实大家都发现了点什么,那就是:只要我们能在业务组件中知道Application的生命周期,那么我们就可以在Application onCreate 时将业务组件中的Fragment添加到Common组件中!那么这个时候我们就需要解决:如何才能让业务组件知道Application的生命周期呢?问题分析到这里,我们看看下面的类图:
首先我们Common组件中定义一个代理接口,这个代理接口定义了Application中的回调方法,然后各个业务组件实现这个代理接口,然后在onCreate方法中做自己想做的事情,而BaseApplication会在调用onCreate方法时找到所有实现了ApplicationDelegate的类,并调用这些实现类的方法,这样业务组件就知道了我们应用程序的生命周期;当业务组件知道应用程序的声明周期后,不仅可以在业务组件中将Fragment添加到Common组件中,而且还可以在业务组件中初始化数据,由于全局Context可以在任何组件中获取,实际上这种方式已经等同于在Application中初始化数据。
如何管理组件
在 Android组件化方案 中,由于所有组件都在同一个项目中,并且使用 compile project(‘:组件名’) 方式依赖其他组件,这样就会导致很多问题。
1. 编译很慢。由于所有的组件工程都在同一个项目中,并且组件之间或app壳工程会依赖其他组件,导致每次打包APP都需要把各个组件编译一次,如果项目中的组件达到十几个后,结果真的很感人!随着组件数量的增长,编译时间几乎呈指数性增加,这个滋味,我想每位Android开发者都深有体会。
2. 组件不方便引用。因为我们的组件是以源代码的形式置于项目中,如果另外一个项目也需要某个组件,这个时候就只能再复制一份代码到新项目中。这就导致一个组件存在于多个项目中,那么最终肯定无法保证这个组件的代码会不会被修改,也就是说组件已经无法保证唯一性了。
**3. 无法控制权限,也不方便混淆。因为项目中包含所有的组件源代码,这时候肯定没有办法控制代码权限了,假如某个组件是另外一个部门或公司提供给你用的,那么他们当然不希望给你源代码。
那么如果解决这些问题呢?我想大多数Android开发者都能想到这个办法。如果你把开源的三方库当做一个功能组件的话,那么很显然,我们在使用这些三方库的时候是通过什么方式呢?难道你会下载它的源代码吗,应该很少有人会这样做吧。那么让我们看看我们是怎么引入三方库的:
compile 'com.github.bumptech.glide:glide:3.8.0'
compile 'io.reactivex.rxjava2:rxjava:2.1.3'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.google.code.gson:gson:2.8.1'
compile 'org.greenrobot:eventbus:3.0.0'
- 1
- 2
- 3
- 4
- 5
- 6
这样大家就很熟悉了,这些开源库一般都是上传到maven或jcenter仓库上供我们引用。那么我们自己开发的组件能不能也传到maven或jcenter仓库呢?当然了不是让你传到开源仓库上去,我的意思是我们可以在公司内部搭建一个私有的maven仓库,将我们开发好的组件上传到这个私有的maven仓库上,然后内部开发人员就可以像引用三方库那样轻而易举的将组件引入到项目中了,这是他们关系就像下图这样:
搭建仓库管理私服主要有如下目的:
- 提升编译性能和可靠性
- 为所有二进制软件组件及其依赖提供配置管理中心
- 为你所在组织和公开仓库提供一个高级可配置的代理
- 建立私有组件发布中心
- 通过改善组件的可用性、版本控制、安全、质量而提升其可维护性和可管理性。
而这也恰好解决了我们在组件化项目中碰到的问题。本来我想将Android组件化项目AndroidModulePattern 中的组件上传到 jitpack ,然后给大家做个演示,但是很可惜,我试了很多次都失败了,大家只能自己试试了。
Android组件化之终极方案的更多相关文章
- Android组件化方案
Android组件化项目地址:Android组件化项目AndroidModulePattern Android组件化之终极方案地址:http://blog.csdn.net/guiying712/ar ...
- Android组件化框架设计与实践
在目前移动互联网时代,每个 APP 就是流量入口,与过去 PC Web 浏览器时代不同的是,APP 的体验与迭代速度影响着用户的粘性,这同时也对从事移动开发人员提出更高要求,进而移动端框架也层出不穷. ...
- 我所理解的Android组件化之通信机制
之前写过一篇关于Android组件化的文章,<Android组件化框架设计与实践>,之前没看过的小伙伴可以先点击阅读.那篇文章是从实战中进行总结得来,是公司的一个真实项目进行组件化架构改造 ...
- Gradle自动实现Android组件化模块构建
背景 随着App的不断迭代,业务会变得越来越复杂,业务模块会越来越多,且每个模块的代码也会变得越来越多.为了应对这一场景,我们需要把不同的业务模块划分成一个个组件,在修改业务代码的时候只需要在对应模块 ...
- 教你打造一个Android组件化开发框架
*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 CC:Component Caller,一个android组件化开发框架, 已开源,github地址:https://github ...
- Android组件化
附:Android组件化和插件化开发 App组件化与业务拆分那些事 Android项目架构之业务组件化 Android组件化核心之路由实现 Android组件化开发实践
- Android 组件化/模块化之路——在展示层搭建MVP结构
Android 组件化/模块化之路——在展示层搭建MVP结构 什么是MVP Model–View–Presenter (MVP) 源于 Model–View–Controller (MVC) 的结构设 ...
- Android组件化demo实现以及遇坑分享
首先贴出demo的github地址:GitHub - TenzLiu/TenzModuleDemo: android组件化demo 作者:TenzLiu原文链接:https://www.jianshu ...
- Android 组件化最佳实践 ARetrofit 原理
本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/TXFt7ymgQXLJyBOJL8F6xg作者:朱壹飞 ARetrofit 是一款针对Android ...
随机推荐
- IntelliJ IDEA快捷键:Ctrl+空格
The Code Completion feature lets you quickly complete different kinds of statements in the code.For ...
- 关于replacePlaceholders
现在还没有完全验证好,有空看看报错信息 https://www.cnblogs.com/fanguangdexiaoyuer/p/5788432.html 1.目录结构 2. package cn.c ...
- Java 分布式系统 实现session共享
当然业界已经有很多成熟的解决方案,我罗列如下: 1.服务器实现的session复制或session共享,这类型的共享session是和服务器紧密相关的,比如webSphere或JBOSS在搭建集群时候 ...
- Selenium Webdriver概述(转)
Selenium Webdriver https://www.yiibai.com/selenium/selenium_overview.html# webdriver自动化俗称Selenium 2. ...
- javascript编写带阴历的黄历
最近在做一个黄历的快应用(quickapp),需要涉及到公历转阴历,效果如下: 快应用(https://www.quickapp.cn/): 快应用是基于手机硬件平台的新型应用形态:标准是由主流手机厂 ...
- 浅谈Spring的AOP实现-代理机制
说起Spring的AOP(Aspect-Oriented Programming)面向切面编程大家都很熟悉(Spring不是这次博文的重点),但是我先提出几个问题,看看同学们是否了解,如果了解的话可以 ...
- 模板 图的遍历 bfs+dfs 图的最短路径 Floyed+Dijkstra
广搜 bfs //bfs #include<iostream> #include<cstdio> using namespace std; ],top=,end=; ][]; ...
- curl请求指定host ip(指定域名解析的内网某ip)
域名www.test.com解析内部多台ip $httpHeader = array('Host: www.test.com');$url = "10.17.2.245/xxx/xxx/t. ...
- BZOJ4065 : [Cerc2012]Graphic Madness
因为两棵树中间只有k条边,所以这些边一定要用到. 对于每棵树分别考虑: 如果一个点往下连着两个点,那么这个点往上的那条边一定不能用到. 如果一个点往下连着一个点,那么这个点往上的那条边一定不能用到. ...
- Linux下Nginx的监控
一.安装Nginx 使用源码编译安装,包括具体的编译参数信息. 正式开始前,编译环境gcc g++ 开发库之类的需要提前装好. 安装make: yum -y install gcc automake ...