赞
踩
为了打造更适合Android的MVVM架构,使用到的技术有AOP、Dagger2、RxJava、Retrofit、Room和Kotlin,并遵循统一的命名规范和调用准则,保证开发时的一致性。
以下是我们现今的架构:
接下来我将展示一下M-V-VM三层之间如何协作,以文章详情页面为例
UI由ArtcileDetailActivity.kt及article_detail_activity.xml组成。
要驱动UI,我们的数据模型需要持有几个元素:
我们将创建一个ArticleDetailViewModel.kt来保存。
一个ViewModel为特定的UI组件提供数据,比如fragment 或者 activity,并负责和数据处理的业务逻辑部分通信,比如调用其它组件加载数据或者转发用户的修改。ViewModel并不知道View的存在,也不会受configuration change影响。
现在我们有了三个文件。
article_detail_activity.xml: 定义页面的UI
ArticleDetailViewModel.kt: 为UI准备数据的类
ArtcileDetailActivity.kt: 显示ViewModel中的数据与响应用户交互的控制器
下面开始实现(为了简单,只显示了主要部分):
<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout>
<android.support.v7.widget.Toolbar
app:title=“@{vm.title}”/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
/**
//data//
lateinit var articleId:Int
val loading=ObservableBoolean(false)
val content = ObservableField()
val title = ObservableField()
//binding//
fun loadArticle():Single
}
}
.doOnSubscribe { startLoad()}
.doAfterTerminate { stopLoad() }
fun startLoad()=loading.set(true)
fun stopLoad()=loading.set(false)
}
/**
override fun getLayoutId(): Int = R.layout.article_detail_activity
@Inject
lateinit var viewModel: ArticleDetailViewModel
//init
override fun initView() {
//统一都是KEY_DATA,别自己瞎命名
val articleID: Int? = intent?.extras?.getInt(Constants.KEY_DATA)
if (articleID == null) {
toast(“文章不存在”, ToastType.WARNING)
finish()
}
getComponent().inject(this)
mBinding.vm = viewModel.apply {
this.articleID = articleID
}
}
//加载数据
override fun loadData() {
viewModel.loadData()
.compose(bindToLifecycle())
// .doOnSubcribe{ showLoadingDialog() }
// .doAfterTerminate{ hideLoadingDialog() }
.subscribe({},{ dispatchFailure(it) })
}
}
他们是如何工作的呢?
在进入到ArticleDetailActivity
页面之后
进入ArticleDetailViewModel
回到ArticleDetailActivity
页面
至此,V-VM之间如何协作就清楚了。
现在我们把View和ViewModel联系了起来,但是ViewModel该如何获取数据呢?
我们使用Retrofit来从后端获取网络数据。
interface ArticleService{
//文章详情
@GET(“article_detail.php”)
fun getArticleDetail(@Query(“id”) id: Int): Single
使用Room数据库来进行持久化
@Dao
interface ArticleDao{
@Query(“SELECT * FROM Articles WHERE articleid= :id”)
fun getArticleById(id:Int):Single
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertArticle(article :Article)
}
然后使用ArticleRepository.kt对网络和本地操作进行一层封装
/**
/* 文章详情
}
先查看本地是否有缓存,如果没有那么再去请求网络,成功后更新本地缓存。
封装成Repository的原因是ViewModel不需要知道它的数据具体是从哪来的,这不是ViewModel这一层需要关心的事情。
即使你的项目没有进行数据缓存,总是从网络拉取数据,也建议封装成Repository,这意味着你的网络层是可以替换的,意义有点类似于封装一个ImageLoadUtil。
总体的流程就这么多,其实弄懂就很简单了。关键点是各层之间职责明确,以及解耦(Dagger2)和使用DataBinding时需要一个统一的规范。
而再细分,优化,也就是进行模块化、组件化的工作,深入些的插件化、热修复等等。不过万丈高楼平地起,我们的地基打的严实,以后的工作才会相对容易。
本文的代码都可以在github.com/ditclear/Pa…中找到
使用Presenter来继承View.OnClickListener
interface Presenter:View.OnClickListener{
override fun onClick(v: View?)
}
然后在BaseActivity/BaseFragment里实现它
abstract class BaseActivity : RxAppCompatActivity(),Presenter{
}
这样当我们要设置点击事件时,只需要
class ArticleDetailActivity : BaseActivity() {
//…
//init
override fun initView() {
mBinding.let{
it.vm=mViewModel
it.presenter=this
}
}
}
在xml中使用时,则统一使用presenter.onClick(view)
方法
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.FloatingActionButton
android:id=“@+id/stow_fab”
android:onClick=“@{(v)->presenter.onClick(v)}”
/>
</android.support.design.widget.CoordinatorLayout>
真正处理则放在相应的Activity/Fragment里
class ArticleDetailActivity : BaseActivity() {
//…
@SingleClick
override fun onClick(v: View?) {
when (v?.id) {
R.id.stow_fab -> stow()
//more …
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
这里我希望可以帮助到大家提升进阶。
内容包含:Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。
喜欢本文的话,不妨给我点个小赞、评论区留言或者转发支持一下呗~
** 这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。
喜欢本文的话,不妨给我点个小赞、评论区留言或者转发支持一下呗~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。