- 01.项目介绍
- 02.项目运行
- 03.项目部分介绍
- 04.项目组件化结构
- 05.项目版本更新
- 06.项目第三方库
- 07.项目遇到bug
- 08.项目截图展示
- 09.项目优化处理
- 10.组件化博客
- 11.其他介绍
- 项目整体架构模式采用:组件化+MVP+Rx+Retrofit+design+Dagger2+阿里VLayout+腾讯X5+腾讯bugly
- 包含的模块:wanAndroid【kotlin】+干货集中营+知乎日报+番茄Todo+微信精选新闻+豆瓣音乐电影小说+小说读书+简易记事本+搞笑视频+经典游戏+其他更多等等
- 此项目属于业余时间练手的项目,接口数据来源均来自网络,如果存在侵权情况,请第一时间告知。本项目仅做学习交流使用,API数据内容所有权归原作公司所有,请勿用于其他用途。
- 可以先下载apk运行到手机上看看效果,下载链接地址:组件化apk案例LifeHelper
- 运行环境要求
- Android studio 版本需要在3.0之上,compileSdkVersion是28,gradle版本是3.2.1,gradle-wrapper是4.6
- 组件模式和集成模式如何切换
- 默认模式下,都是属于library形式的组件【app作为空壳主工程依赖所有的组件】,如果想把某一个library形式的组件切换成一个独立可以run的application,则
- 比如,我想把视频模块,也就是该项目中的video组件切换成可运行的项目。如果想了解组件化更多内容,可以着重看 04.项目组件化结构部分说明
- 修改yc.gradle文件中,直接将对应的开关置为true即可,然后需要Sync一下,就可以运行该模块
- 将isVideoApplication = true,就可以切换成application模块,与app主工程解绑,实际开发中,比如你负责这个模块,那么你运行的时候,直接编译该模块,不会编译整个项目而导致耗费大量时间。
- 同理,设置成false,即可还原成library形式的组件,与app主工程绑定[也就是被主工程依赖]
ext { isAndroidApplication = false //玩Android模块开关,false:作为Lib组件存在, true:作为application存在 isVideoApplication = true //视频模块开关,false:作为Lib组件存在, true:作为application存在 isNoteApplication = false //记事本模块开关,false:作为Lib组件存在, true:作为application存在 isGameApplication = false //游戏模块开关,false:作为Lib组件存在, true:作为application存在
- 模块众多,如何统一修改第三方库,以及build.gradle中的配置信息
- 已经抽取了公共的build.gradle,详细的代码,可以直接看项目根目录下的yc.gradle文件,修改版本即可
- 切换网络请求方式,比如公司正式项目就有:正式线上环境,测试环境,仿真环境等等
- 那么如何统一切换呢,直接修改项目根目录下的url.properties文件即可。由于该项目众多接口是网络接口,因此该项目只是提供切换环境的思路代码。
//修改TEST_URL即可,0测试环境,1仿真环境,2正式环境 TEST_URL=0 PREVIEW_URL=1 RELEASE_URL=2
- 那么如何统一切换呢,直接修改项目根目录下的url.properties文件即可。由于该项目众多接口是网络接口,因此该项目只是提供切换环境的思路代码。
- 编译时间
- 编译遇到问题
- 看看7.1 编译报错bug,如果没有找到解决方案,建议谷歌查询一下问题。
- 新闻部分(天行新闻,微信精选新闻,阿里云热门新闻,干货集中营新闻等等)
- 干货集中营:包含福利,搜索,每日技术新闻,休息视频等众多模块
- 音乐部分(音乐播放器,自动搜索本地音乐文件,在线音乐是百度音乐api)
- 播放本地音乐,网络音乐[支持下载,播放,分享],搜索音乐
- 视频部分(视频播放器,自动搜索本地视频文件,还有许多网络搞笑视频)
- 图片部分(干货集中营美女图片),画廊浏览高清大图
- 豆瓣电影,音乐,读书(豆瓣接口)
- 简易ToDo记事本,番茄周,学习MVP+Dagger2时写的。
- 超文本笔记本,可以支持文字,图片,动态图混排,做便签十分方便,注意高清图片会压缩,目前笔记是保存本地
- 技术分享部分(鸿洋玩Android,还有代码家的干活集中营等等),关于flutter版本的极致体验玩Android客户端
- 玩Android,鸿洋大神的开放接口,
- 首页轮播图+list:推荐最新的博客
- 知识体系:对安卓知识体系做整理
- 登录注册:登录、注册、Cookie持久化
- 我的收藏页面:依靠Cookie持久化,实现对文章的收藏和展示
- 项目分类:在WanAndroid上发布的项目
- 网址导航:展示常用的开发网站
- 搜索功能:输入搜索、搜索推荐、历史搜索等等
- 关于我们:鸿洋wanAndroid介绍
- love爱意表达部分,程序员表白神器,简易含蓄的单身程序员可以看看该模块,可以给女朋友一个惊喜!
- 玩Android部分,接口是鸿洋大神开放的api,学习kotlin时所写
- markDown格式笔记本,支持md格式,数据是保存到本地。对于程序员,markDown是十分方便记录笔记
- 游戏部分,包括智慧拼图,还有童年飞机大战游戏,体验非常好玩。
- 其他部分,几乎融合了自己开源的大部分封装库,比如,状态管理,视频库,轮播图,幸运大转盘[老虎机],画廊,自定义进度条,图片缩放,线程池
- 侧滑菜单:DrawerLayout+NavigationView
- 基本遵循Google Material Design设计风格
- 透明状态栏使用与版本适配
- 图片加载picasso,Glide加载监听,获取缓存,圆角图片,高斯模糊
- list条目点击水波纹效果
- CoordinatorLayout+Behavior实现标题栏渐变
- 自定义RecyclerView下拉刷新上拉加载,支持加载loading,空页面,异常界面,有数据界面状态切换
- 缓存使用Realm数据库,做数据的增删改查
- 状态管理库与Activity和Fragment结合,可以自由切换不同的状态
- 项目代码规范;布局优化;代码优化;架构优化;内存泄漏优化;线程优化;Bitmap优化;网络优化;懒加载优化,启动页优化;静态变量优化;电量性能优化;view控件异常销毁保存重要信息优化;去除淡黄色警告优化;使用注解替代枚举优化;glide加速优化;多渠道打包优化状态管理切换优化;TrimMemory和LowMemory优化;轮询操作优化
- 具体可以看目录09.项目优化处理部分内容!!!
- 传统APP架构图
- 存在的问题
- 主工程:
- 除了一些全局配置和主 Activity 之外,不包含任何业务代码。有的也叫做空壳app
- 业务组件:
- 最上层的业务,每个组件表示一条完整的业务线,彼此之间互相独立。
- 该案例中分为:干活集中营,玩Android,知乎日报,微信新闻,头条新闻,搞笑视频,百度音乐,我的记事本,豆瓣音乐读书电影,游戏组件等等。
- 功能组件:
- 该案例中分为,分享组件,评论反馈组件,支付组件,画廊组件等等。同时注意,可能会涉及多个业务组件对某个功能组件进行依赖!
- 基础组件:
- 支撑上层业务组件运行的基础业务服务。
- 该案例中:在基础组件库中主要有,网络请求,图片加载,通信机制,工具类,分享功能,支付功能等等。当然,我把一些公共第三方库放到了这个基础组件中!
- 传统以前工程下模块
- 记得刚开始进入Android开发工作时,只有一个app主工程,后期几乎所有的需求都写在这个app主工程里面。只有简单的以业务逻辑划分的文件夹,并且业务之间也是直接相互调用、高度耦合在一起的。
- 导致后期改项目为组件化的时候十分痛苦,不同模块之间的业务逻辑实在关联太多,但还是没办法,于是按照步骤一步步实践。终极目标是,告别结构臃肿,让各个业务变得相对独立,业务组件在组件模式下可以独立开发。
- 组件化模式下如何通信
- 这是组件化工程模型下的业务关系,业务之间将不再直接引用和依赖,而是通过“路由”这样一个中转站间接产生联系。在这个开源项目中,我使用的阿里开源的路由框架。关于Arouter基础使用和代码分析,可以看我这篇博客:Arouter使用与代码解析
- 那么问题有哪些呢?
- 组件化时资源名冲突该怎么办?比如,color,shape,drawable,图片资源,布局资源,或者anim资源等等,都有可能造成资源名称冲突。这是为何了,有时候大家负责不同的模块,如果不是按照统一规范命名,则会偶发出现该问题。
- 业务组件之间联动导致耦合严重?比如,实际开发中,购物车和首页商品分别是两个组件。但是遇到产品需求,比如过节做个活动,发个购物券之类的需求,由于购物车和商品详情页都有活动,因此会造成组件经常会发生联动。
- 如何做到各个组件化模块能获取到全局上下文?
- 组件在lib和app之间进行切换,如何处理butterKnife使用问题呢?
- 当组件是lib时,写代码需要注意哪些语法?
- 不要乱发bus消息?如果项目中大量的使用eventbus,那么会看到一个类中有大量的onEventMainThread()方法,写起来很爽,阅读起来很痛苦。
- 页面跳转存在问题?比如,跳转页面需要登陆状态如何拦截,跳转页面传递参数该怎么办,程序意外跳转异常或者失败又该如何处理?
- 使用Arouter注意事项有哪些?如何让代码变得更加容易让人维护?
- 直接看我这篇博客:
- 动态的管理组件,所以给每个组件添加几个生命周期状态:加载、卸载和降维。为此我们给每个组件增加一个ApplicationLike类,里面定义了onCreate和onStop两个生命周期函数。
- 看到网上有个方案说:主项目负责加载组件,由于主项目和组件之间是隔离的,那么主项目如何调用组件ApplicationLike的生命周期方法呢,目前采用的是基于编译期字节码插入的方式,扫描所有的ApplicationLike类(其有一个共同的父类),然后通过javassist在主项目的onCreate中插入调用ApplicationLike.onCreate的代码。那么思路有了,具体代码该如何实现?
- 在网上看到很多博客说,如何拆分组件,按模块拆分,或者按照功能拆分。但很少有提到fragment在拆分组件时的疑问,这个让我很奇怪。
- 先来说一个业务需求,比如一个购物商城app,有4个模块,做法一般是一个activity+4个fragment,这个大家都很熟悉,这四个模块分别是:首页,发现,购物车,我的。然后这几个页面是用fragment写的,共用一个宿主activity,那么在做组件化的时候,我想把它按照业务拆分成首页,发现,购物车和我的四个独立的业务模块。
- 遇到疑问:
- 如果是拆分成四个独立的业务模块,那么对应的fragment肯定要放到对应的组件中,那么这样操作,当主工程与该业务组件解绑的情况下,如何拿到fragment和传递参数进行通信。
- Fragment 中 开启Activity带requestCode,开启的Activity关闭后,不会回调Fragment中的onActivityResult。只会调用Fragment 所在Activity的onActivityResult。
- 多fragment单activity拦截器不管用,难道只能用于拦截activity的跳转?那如果是要实现登录拦截的话,那不是只能在PathReplaceService中进行了?
- 网络解决办法
- 第一个疑问:由于我使用阿里路由,所以我看到zhi1ong大佬说:用Router跳转到这个Activity,然后带一个参数进去,比方说tab=2,然后自己在onCreate里面自行切换。但后来尝试,还是想问问广大程序员有没有更好的办法。
- 第二个疑问:还是zhi1ong大佬说,通过广播,或者在Activity中转发这个事件,比方说让Fragment统一依赖一个接口,然后在Activity中转发。