Android mvvm arch的一次架构实现

项目地址:mvvmClient

兄dai,2019的寒冷不知道你感受到了没,反正我已经两个月没有发工资了,作为一个开发没有了工资就等于没有了灵魂,但一切为了运行的更加丝滑,哥们把一篇mvvmClient奉上。

先放图


屏幕快照 2019-01-06 上午11.00.01.png
屏幕快照 2019-01-06 上午11.01.05.png
屏幕快照 2019-01-06 上午11.02.05.png

....

就这些了,毕竟这次界面不是重点,接下来进入主题

  1. 项目架构
    模块之间解耦使用arouter,每个模块可以自己单独运行起来。代码解藕使用dagger2。
    使用mvvm架构,整体严格按照Architecture Component规范,统一数据源

2.用到的第三方库


屏幕快照 2019-01-06 上午11.08.36.png

3.项目目录结构

app // 壳app
library_core // 核心库 提供基础的网络操作
library_common // 公共库
module_account // 登录模块
module_player // 玩Android api 简单实现

屏幕快照 2019-01-06 上午11.13.20.png
屏幕快照 2019-01-06 上午11.14.32.png

4.数据流转具体逻辑
repository层
根据本次请求的请求策略来决定从网络还是从数据库(缓存,使用room)获取数据,提供给viewmodel 层的是livedata viewmodel层 从repository中拿到数据后处理方式有很多种。
a. 直接把数据提供给UI层,UI层来渲染对应的view(databinding)
b. 处理和加工数据,把livedata数据转化为 MediatorLiveData,通过MediatorLiveData把数据拆分为多个更加具体的livedata传递给UI(推荐用法)
UI层 负责展示和渲染(databinding)

5.解决的问题
使用dagger2模块化开发的一次尝试,dagger2解藕后的多个模块单独运行的一个思路 遵守Android arch 规范的实现 适合敏捷开发和项目规模比较大的开发模式

6.整体流程

如果关注点是使用该框架,那么其实整体用法还是固定的,先说说用法吧

a. 新建功能模块module,名字假如为moduleTest目录结构按照 moduleplayer的就可以,当然需要你在project 目录下,创建debug 目录,这是为了使你的moduleTest
能够自己起飞,单独作为一个项目来运行, 在debug目录下新建你的application,继承baseapplication实现initDi(); 把相关的依赖配置好,然后component(这里假如你会使用dagger2)

b. 到项目真正功能的开发了,那就说说分包
api -- retorfit的数据接口
db -- 数据库相关(如果你要自己维护缓存,那这个地方需要你自己来写,用的room,如果缓存策略能满足你的开发,那这个地方可以忽略,当然后期会加入etag cache-control等默认服务端缓存策略)
di -- 注入 api下的数据接口,ui相关的activity fragment viewmodel 都是在这个地方注入的,至于是怎么注入的这个问题后面讲
repository -- 仓库,我们不提供数据,我们只是数据的搬运工。数据的获取是在这里,因此所有请求的响应你都能在这里看到她的身影
ui -- 这个不说了,我知道你肯定是Android开发 emmm... 还是说下吧 activity fragment 中的职责就是控制view层,响应用户操作,所以不要把处理业务的逻辑放在这里,
可以放到viewmodel中来处理,然后再通过具体的livedata驱动UI层的view作出响应,所以他们应该是简介的,只监听livedata的变化,把这变化传递给view,xml使用databinding,(我这里没有使用太多,原则
上讲可以多用一些bindingadapter,但是我总觉得有点本末倒置了,数据驱动就要在xml中处理过多的逻辑,这让我想到了java的jsp,和php,我们是为了维护访方便,解藕清晰才框架的,不是吗?这个就自己考虑吧,没有定义binding包是因为我到现在也没说服自己)
viewmodel -- 这一层和mvp的p层有点像,但是更加丝滑(个人感觉),数据处理不再考虑生命周期的限制,从repository拿到数据可以加工也可直接使用(建议加工后成为具体有意义的数据再给UI层,应为不加工的后果可能是把你的架构变成了mvc,哈哈哈,我就是从这走过来的)
vo -- 这个就是请求的实体类,当然如果自己维护缓存,也可以当作room的entity层,使用提供的缓存的话,就把你要缓存的实体实现Serializable
widget -- 控件

c. 框架的构建流程

1.依赖关系
从builde.gradle(app)中能看的出来 整体的依赖规则

if (!IsBuildMudle.toBoolean()) {
implementation project(':moduleAccount')
implementation project(':moduleGank')
implementation project(':moduleplayer')
} else {
implementation project(':library_core')
}

每个模块的都依赖 api project(':library_core')

library_core依赖library_common

  1. library_core 的职责

library_core 提供基础的网络请求模块,基础的注入模块,一些工具类(后期放到common中),可以看到没有components ,这是因为踩坑dagger2的时候(有时间再探探这个坑,或者有dagger2大神给解决下,总觉得目前的不完美)没能使用dependencies和subcomponent这些姿势来解决多个components之间的依赖
,所以用了不是很完美的一个components 多个module的实现方式,还算丝滑,使用dagger-android来做的四大组件的注入,在baseappliction中暴露initDi方法供继承者注入自己的四大组件,当然了需要实现baseactitivity 或者 basefragment,因为他们的注入是在activity的oncreate中注入了,这时候你可能会问,为什么不再baseactivity中统一注入呢,
毕竟baseactivity 的handactivity 会holader住所有activity的创建,这个问题我也想过,这姿势肯定很爽,但是我没能实现,一直报错让我不得已用了现在这个姿势,至于出错的原因是什么呢?我想是跟上面说的 dagger2的dependencies和subcomponent有关,这个留着以后探索。至于注入这方面的就不多讲了
网络请求使用的retorfit 加 LiveDataCallAdapterFactory,livedatacalladapter显得有些脆弱,这里是用的网上找来的,后续会自己动手让她strong一点,至于拦截器这些就不多说了。
好了关键的网络请求和注入大致就是上面这些了

  1. library_common 的职责
    这个就随意些了,common都很熟悉,目前只是把arouter的跳转path的定义和一些工具类放在这里了。存在的意义是我觉从一开始觉得library_core在开发的时候不要频繁的动,common来处理一些公共资源

  2. 看完上面这些如果还是迷茫的,那不是你的错,我的。。好吧,自己撸一遍登录注册就明白了(嘿嘿嘿)

  3. 未完待续..

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容