赞
踩
前言
协程是一种并发设计模式,您可以在 Android 平台上使用它来简化异步执行的代码。协程是在版本 1.3 中添加到 Kotlin 的,它基于来自其他语言的既定概念。
在 Android 上,协程有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。使用协程的专业开发者中有超过 50% 的人反映使用协程提高了工作效率。本主题介绍如何使用 Kotlin 协程解决以下问题,从而让您能够编写出更清晰、更简洁的应用代码。
协程是我们在 Android 上进行异步编程的推荐解决方案。值得关注的特点包括:
View:Activity/Fragment
ViewModel:Jetpack ViewModel & Jetpack LiveData
Model:Repository仓库,包含本地持久性数据和服务端的数据
以下是Google Android官网对LiveData和ViewModel的定义
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。
1、项目中使用到的库
- // Kotlin
- implementation "androidx.activity:activity-ktx:1.2.0"
- implementation 'androidx.fragment:fragment-ktx:1.2.5'
-
- //协程
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
-
- //retrofit
- implementation 'com.squareup.retrofit2:retrofit:2.9.0'
- implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
2、创建retrofit和okhttpclient的静态类
- object RetrofitClient {
-
- private const val BASE_URL = "https://wanandroid.com/"
-
- private var retrofit: Retrofit? = null
-
- val service: HttpService by lazy {
- getRetrofit().create(HttpService::class.java)
- }
-
- private fun getRetrofit(): Retrofit {
- if (retrofit == null) {
- retrofit = Retrofit.Builder()
- .baseUrl(BASE_URL)
- .client(getOkHttpClent())
- .addConverterFactory(GsonConverterFactory.create())
- //.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .build()
- }
- return retrofit!!
- }
-
-
- private fun getOkHttpClent(): OkHttpClient {
- val builder = OkHttpClient().newBuilder()
-
- val cacheFile = File(MyApplication.instance.cacheDir, "cache")
- val cache = Cache(cacheFile, 1024 * 1024 * 50)// 50M 的缓存大小
-
- builder.run {
- cache(cache)
- connectTimeout(60, TimeUnit.SECONDS)
- readTimeout(60, TimeUnit.SECONDS)
- writeTimeout(60, TimeUnit.SECONDS)
- retryOnConnectionFailure(true)//错误重连
- }
-
- return builder.build()
- }
-
- }
3、新建接收数据的基类
- //接受数据的基类
- data class ResponseData<out T>(
-
- val errorCode: Int,
- val errorMsg: String,
- val data: T
- )
-
- //获取banner为例
- data class Banner(
- val desc: String,
- val id: Int,
- val imagePath: String,
- val isVisible: Int,
- val order: Int,
- val title: String,
- val type: Int,
- val url: String
- )
4、新建基类中间层BaseRepository,统一处理请求结果
- open class BaseRepository {
-
- suspend fun <T : Any> request(call: suspend () -> ResponseData<T>): ResponseData<T> {
- return withContext(Dispatchers.IO) {
- call.invoke()
- }.apply {
- LogUtil.e("接口返回数据---------->,${this}")
- when (errorCode) {
- 0, 200 -> this
- 100, 401 -> ""
- 403 -> ""
- 404 -> ""
- 500 -> ""
- else -> ""
-
- }
- }
- }
-
- }
5、新建ViewModel的基类BaseViewModel
- open class BaseViewModel : ViewModel(), LifecycleObserver {
-
-
- //运行在UI线程的协程
- fun launchUI(block: suspend CoroutineScope.() -> Unit) = viewModelScope.launch {
- try {
- withTimeout(15 * 1000) {
- block()
- }
- } catch (e: Exception) {
- //此处接收到BaseRepository里的request抛出的异常
- //根据业务逻辑自行处理代码...
-
- }
- }
-
-
- }
6、新建BaseActivity,做一些简单的封装
- abstract class BaseActivity<T : ViewBinding, VM : ViewModel> : AppCompatActivity() {
-
- lateinit var binding: T
- protected lateinit var viewModel: VM
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = getViewBinding()
- providerVMClass()?.let {
- viewModel = ViewModelProvider(this).get(it)
- }
- setContentView(binding.root)
- initView()
- setListener()
-
- }
-
- abstract fun providerVMClass(): Class<VM>?
-
- protected abstract fun getViewBinding(): T
-
- abstract fun initView()
-
- abstract fun setListener()
- }
7、以请求banner模块为例,撸一遍代码
- interface HttpService {
-
-
- @GET("banner/json")
- suspend fun getBanner(): ResponseData<List<Banner>>
-
-
- }
-
- class BannerRepository : BaseRepository() {
-
- suspend fun getBanner(): ResponseData<List<Banner>> = request {
- RetrofitClient.service.getBanner()
- }
-
-
- }
-
- class BannerViewModel : BaseViewModel() {
-
- private val repository by lazy {
- BannerRepository()
- }
-
- private val bannerData by lazy {
- MutableLiveData<List<Banner>>()
- }
-
- fun getBanner(): LiveData<List<Banner>> {
-
- launchUI {
- val result = repository.getBanner()
- bannerData.value = result.data
- }
-
- return bannerData
- }
- }
-
- class BannerActivity : BaseActivity<ActivityBannerBinding, BannerViewModel>() {
-
-
- override fun getViewBinding() = ActivityBannerBinding.inflate(layoutInflater)
-
- override fun initView() {
- viewModel.getBanner().observe(this, { it ->
- it.forEach {
- LogUtil.e(it.imagePath)
- }
- })
- }
-
- override fun setListener() {
- }
-
-
- override fun providerVMClass() = BannerViewModel::class.java
- }
8、一个retrofit配合kotlin 协程的MVVM模式的网络请求框架搭建好了
//自己总结的,可以参考一下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。