Kotlin-+-协程-+-Retrofit-,2024Android面试心得

class ArticleRepository {
suspend fun getDatas(): DataBean {
return RetrofitClient.reqApi.getDatas().await()
}
}

在Activity中代码如下

private fun initData() {
model.getActicle().observe(this, Observer{
//获取到数据
toolbar.setBackgroundColor(Color.RED)
})
}

后续优化

1.内存泄漏问题解决方案

结和了各位大佬们的意见,将使用GlobalScope可能会出现内存泄漏的问题进行了优化。因为在协程进行请求的过程中,若此时ViewModel销毁,里面的协程正在请求的话,将无法销毁,出现内存泄漏,所以在ViewModel onCleared 里面,即使结束协程任务,参考代码如下。

open class BaseViewModel : ViewModel(), LifecycleObserver{
private val viewModelJob = SupervisorJob()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
//运行在UI线程的协程
fun launchUI( block: suspend CoroutineScope.() -> Unit) {
try {
uiScope.launch(Dispatchers.Main) {
block()
}
}catch (e:Exception){
e.printStackTrace()
}
}
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
}

当然,最好的方式是使用viewModelScope,但是我在引入该包的时候,会报错,由于最近比较忙暂时还没来得急解决,后续问题有时间我也会继续修改,还望各位大佬能帮忙指点

2.优化请求代码

先看下之前的请求代码

private suspend fun getData() {
val result = withContext(Dispatchers.IO){
// delay(10000)
repository.getDatas()
}
datas.value = result
}

每一次都需要写个withContext(),实际运用中,感觉有点不方便,于是乎想了一下,怎么才能给他封进请求方法里面? 代码如下

open class BaseRepository {
suspend fun request(call: suspend () -> ResponseData): ResponseData {
return withContext(Dispatchers.IO){ call.invoke()}
}
}

通过在BaseRepository里面写了一个专门的请求方法,这样每次只需执行request就行了 请求参考如下

class ArticleRepository : BaseRepository() {
suspend fun getDatas(): ResponseData<List> {
return request {
delay(10000)
Log.i(ScrollingViewModel::class.java.simpleName,“loadDatas1 run in ${Thread.currentThread().name}”)
RetrofitClient.reqApi.getDatas().await() }
}
}

注:这个 delay(10000)只是我测试用的,意思是休眠当前协程,防止萌新在自己项目中加上了,还是有必要说一下的

再看看ViewModel中就太简单了

class ScrollingViewModel : BaseViewModel() {
private val TAG = ScrollingViewModel::class.java.simpleName

private val datas: MutableLiveData<List> by lazy { MutableLiveData<List>().also { loadDatas() } }

private val repository = ArticleRepository()
fun getActicle(): LiveData<List> {
return datas
}

private fun loadDatas() {
launchUI {
Log.i(TAG,“loadDatas1 run in ${Thread.currentThread().name}”)
val result = repository.getDatas()
Log.i(TAG,“loadDatas3 run in ${Thread.currentThread().name}”)
datas.value = result.data
}
// Do an asynchronous operation to fetch users.
}
}

注意看请求部分,就两句话,一句发起请求val result = repository.getDatas(),然后就是为我们的LiveData赋值了,看起有没有同步代码的感觉,这就是协程的魅力所在,为了验证我们的请求没有阻塞主线程,我打印了日志

06-19 12:26:35.736 13648-13648/huaan.com.mvvmdemo I/ScrollingViewModel: loadDatas start run in main
06-19 12:26:45.743 13648-13684/huaan.com.mvvmdemo I/ScrollingViewModel: request run in DefaultDispatcher-worker-1
06-19 12:26:46.227 13648-13648/huaan.com.mvvmdemo I/ScrollingViewModel: loadDatas end run in main

看到了吧,各司其职,效果很棒

异常处理

搞了半天才发现没有弄异常处理,当请求失败之后,项目就崩溃了,这不是是我们想要的结果,由于好没有想到更好的处理方式,只能在外面套个tyr catch 顶一顶了,参考如下

open class BaseViewModel : ViewModel(), LifecycleObserver{
private val viewModelJob = SupervisorJob()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
private val error by lazy { MutableLiveData() }
private val finally by lazy { MutableLiveData() }
//运行在UI线程的协程
fun launchUI( block: suspend CoroutineScope.() -> Unit) {
uiScope.launch(Dispatchers.Main) {
try {
block()
}catch (e:Exception){
error.value = e
}finally {
finally.value = 200
}
}
}
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
/**

  • 请求失败,出现异常
    /
    fun getError(): LiveData {
    return error
    }
    /
    *
  • 请求完成,在此处做一些关闭操作
    */
    fun getFinally(): LiveData {
    return finally
    }
    }

结语

上面只是描述了一些实现过程,具体使用还得参考demo,基本上能满足大部分的需求,要是感兴趣的小伙伴,可以下载demo参考,感觉不错的话,顺手点个赞就很满足了。于所学不精,可能会有使用不当之处,希望各位大佬能指出不当的地方,深表感谢。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

小福利:

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

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

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

2021大厂最新Android面试真题解析

Android大厂面试真题解析

各个模块学习视频:如数据结构与算法

算法与数据结构资料图

只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
一线互联网架构师

这份体系学习笔记,适应人群:**第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。**第二,**开发几年,不知道如何进阶更进一步,比较迷茫。第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!点赞+评论即可获得!

直接点击这里前往我的GitHub中下载,就可以白嫖啦,记得给文章点个赞哦。

第二,**开发几年,不知道如何进阶更进一步,比较迷茫。第三,到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!点赞+评论即可获得!

直接点击这里前往我的GitHub中下载,就可以白嫖啦,记得给文章点个赞哦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值