2024年安卓最新使用Kotlin构建更适合Android的MVVM应用程序,面试经历分享怎么写

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

七大模块学习资料:如NDK模块开发、Android框架体系架构…

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。

这份体系学习笔记,适应人群:
**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。
**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。
第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!
由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

View层的关注点是显示数据,接收用户的操作,调用ViewModel中的方法

为了打造更适合Android的MVVM架构,使用到的技术有AOP、Dagger2、RxJava、Retrofit、Room和Kotlin,并遵循统一的命名规范和调用准则,保证开发时的一致性。

以下是我们现今的架构:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建文章详情界面

接下来我将展示一下M-V-VM三层之间如何协作,以文章详情页面为例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

V—VM

UI由ArtcileDetailActivity.kt及article_detail_activity.xml组成。

要驱动UI,我们的数据模型需要持有几个元素:

  • Article Id:文章详情的id,用于加载文章详情
  • title:文章的标题
  • content:文章的内容
  • state:加载状态,用一个State类来封装

我们将创建一个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>

/**

  • 页面描述:ArticleDetailViewModel
  • @param repo 数据源Model(MVVM 中的M),负责提供ViewModel中需要处理的数据
  • Created by ditclear on 2017/11/17.
    */
    class ArticleDetailViewModel @Inject constructor(val repo: ArticleRepository) {

//data//
lateinit var articleId:Int
val loading=ObservableBoolean(false)
val content = ObservableField()
val title = ObservableField()

//binding//
fun loadArticle():Single

=
repo.getArticleDetail(articleId)
.async()
.doOnSuccess { t: Article? ->
t?.let {
title.set(it.title)
content.set(it.content)

}
}
.doOnSubscribe { startLoad()}
.doAfterTerminate { stopLoad() }

fun startLoad()=loading.set(true)
fun stopLoad()=loading.set(false)
}

/**

  • 页面描述:ArticleDetailActivity,处理和用户的交互(点击事件),以及处理
  • viewModel层回调的数据,附加一些显示Loading,空状态和绑定生命周期等等的操作
  • Created by ditclear on 2017/11/17.
    */
    class ArticleDetailActivity : BaseActivity() {

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页面之后

  1. init()方法->先进行数据的初始化,将viewModel和xml文件进行绑定
  2. loadData()方法->调用viewModel的方法

进入ArticleDetailViewModel

  1. 调用Model层获取详情方法获取数据源
  2. 根据需要使用RxJava操作符对数据进行转换,通过DataBinding更新UI
  3. 返回可观测的Single对象给View

回到ArticleDetailActivity页面

  1. 绑定生命周期,避免内存泄漏
  2. 对返回的可观测对象进行订阅
  3. 处理成功和失败的情况

至此,V-VM之间如何协作就清楚了。

M—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对网络和本地操作进行一层封装

/**

  • 页面描述:ArticleRepository
  • 提供数据给ViewModel层 , 处理网络数据和本地缓存之间的关系
  • Created by ditclear on 2017/11/17.
    */
    class ArticleRepository @Inject constructor
    (private val remote: ArticleService, private val local: ArticleDao) {

/* 文章详情

  • 先查看本地是否有缓存,如果没有那么再去请求网络,成功后更新本地缓存
    */
    fun getArticle(articleId: Int): Single
    =
    local.getArticleById(articleId).onErrorResumeNext {
    if (it is EmptyResultSetException) {
    remote.getArticleDetail(articleId).doOnSuccess { t -> t?.let { local.insertArticle(it) } }
    } else throw it
    }

}

先查看本地是否有缓存,如果没有那么再去请求网络,成功后更新本地缓存。

封装成Repository的原因是ViewModel不需要知道它的数据具体是从哪来的,这不是ViewModel这一层需要关心的事情。

即使你的项目没有进行数据缓存,总是从网络拉取数据,也建议封装成Repository,这意味着你的网络层是可以替换的,意义有点类似于封装一个ImageLoadUtil。

总体的流程就这么多,其实弄懂就很简单了。关键点是各层之间职责明确,以及解耦(Dagger2)和使用DataBinding时需要一个统一的规范。

而再细分,优化,也就是进行模块化、组件化的工作,深入些的插件化、热修复等等。不过万丈高楼平地起,我们的地基打的严实,以后的工作才会相对容易。

本文的代码都可以在github.com/ditclear/Pa…中找到

一些建议

建议一:在Activity或Fragment里处理点击事件

使用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)方法

最后

我的面试经验分享可能不会去罗列太多的具体题目,因为我依然认为面试经验中最宝贵的不是那一个个具体的题目或者具体的答案,而是结束面试时,那一刻你的感受以及多天之后你的回味~

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值