协程+Retrofit+ViewModel+LiveData+DataBinding

介绍协程+Retrofit+ViewModel+LiveData+DataBinding的框架搭建,实现从网络请求api接口功能,相关demo

一、框架搭建

整体项目结构如下

image-20220127202810611

1.1、环境、依赖库配置

新建项目,在app的build.gradle中添加依赖

    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'

    //coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'

    //viewModels
    implementation "androidx.activity:activity-ktx:1.1.0"

因为涉及到http网络请求,配置manifest权限

<uses-permission android:name="android.permission.INTERNET" />

application节点下的http权限

android:networkSecurityConfig="@xml/network_security_config"

xml -> network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

app的build.gradle中配置databinding

android {
    ...
    dataBinding {
        enabled = true
    }
}

gradle.properties中配置debug包运行

android.injected.testOnly=false

1.2、创建api网络请求

新建UserApi.kt,这里简单实现数据解析的User实体类,服务器返回json

{
    "name": "jason",
    "address": "California"
}
// 定义User数据实体类
data class User(val name: String, val address: String)

// retrofit网络请求
val userServiceApi: UserServiceApi by lazy {
    val retrofit = retrofit2.Retrofit.Builder()
        .client(OkHttpClient.Builder().addInterceptor {
            it.proceed(it.request()).apply {
                Log.d("jason", "request:${code()}")
                //Log.d("jason", "boy:${body()?.string()}")
            }
        }.build())
        .baseUrl("http://81.68.175.49:8080/kotlinstudyserver/")
        .addConverterFactory(MoshiConverterFactory.create())
        .build()
    retrofit.create(UserServiceApi::class.java)
}

// 请求接口
interface UserServiceApi {

    @GET("user")
    fun loadUser(@Query("name") name: String) : Call<User>

    @GET("user")
    suspend fun getUser(@Query("name") name: String) : User
}

1.3、创建viewmodel

创建MainViewModel继承自ViewModel()

class MainViewModel: ViewModel() {
}

根据google官方指南,我们是在ViewModel中通过repository去请求网络、数据库的数据

因此这里还需要新建UserRepository

class UserRepository {
    suspend fun getUser(name: String): User {
        return userServiceApi.getUser(name)
    }
}

因为这里继承自ViewModel,所以这里带了viewModelScope

MainViewModel部分代码:

class MainViewModel: ViewModel() {
    //liveData
    val userLiveData = MutableLiveData<User>()

    private val userRepository = UserRepository()

    fun getUser(name: String) {
        viewModelScope.launch {
            userLiveData.value = userRepository.getUser(name)
        }
    }
}

1.4、加载数据

activity_main.xml中绘制mvvm绑定视图

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="viewModel"
            type="com.example.retrofitviewmodellivedatadatabinding.viewmodel.MainViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <Button
            android:id="@+id/submitButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="104dp"
            android:text="提交"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline" />

        <TextView
            android:id="@+id/nameTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.userLiveData.name}"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline"
            app:layout_constraintHorizontal_bias="0.484"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.681" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.5" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

activity中加载数据set到布局上

class MainActivity : AppCompatActivity() {
    private val mainViewModel: MainViewModel by viewModels()

    @SuppressLint("StaticFieldLeak")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 设置布局
        val binding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        // 指定viewModel
        binding.viewModel = mainViewModel
        // 在 xml 中使用 LiveData
        binding.lifecycleOwner = this
        binding.submitButton.setOnClickListener {
            mainViewModel.getUser("xxx")
        }
    }
}

二、设计好在哪里

2.1、viewModel解决Activity很可能会被销毁重建,页面的状态将会丢失

如下图所示页面旋转时,CoroutineDemo数据销毁了,而使用了ViewModel的数据仍然存在

image-20220127202810611

2.2、协程解决了回调地狱的问题

在网络请求中,协程将异步任务同步化,优化了代码可读性

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我来回答你的问题。 首先,Kotlin 是一种基于 JVM 的静态类型编程语言,它的语法简洁易懂,支持函数式编程和面向对象编程。 协程Kotlin 中的一种轻量级线程,可以实现异步编程和并发执行。Retrofit 是一款网络请求库,它可以帮助我们轻松地实现网络请求和数据解析。MVVM 是一种软件架构模式,可以将应用程序分为三个部分:模型、视图和视图模型。 下面是一个基于 Kotlin + 协程 + Retrofit + MVVM 的网络请求的优雅实现: 1. 定义 API 接口 首先定义 API 接口,使用 Retrofit 注解来描述请求方法和参数。 ```kotlin interface ApiService { @GET("api/news") suspend fun getNews(@Query("category") category: String): NewsResponse } ``` 2. 创建数据模型 根据 API 接口的返回数据,我们可以创建一个数据模型。 ```kotlin data class News(val title: String, val content: String) data class NewsResponse(val code: Int, val message: String, val newsList: List<News>) ``` 3. 创建 ViewModel ViewModel 是连接数据模型和视图的中间层,它处理数据逻辑并提供可观察的数据。 ```kotlin class NewsViewModel : ViewModel() { private val _newsList = MutableLiveData<List<News>>() val newsList: LiveData<List<News>> = _newsList fun loadNews(category: String) { viewModelScope.launch { val response = retrofit.create(ApiService::class.java).getNews(category) if (response.code == 200) { _newsList.value = response.newsList } } } } ``` 4. 创建视图 视图负责展示数据,并与用户交互。 ```kotlin class NewsActivity : AppCompatActivity() { private val viewModel by viewModels<NewsViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_news) viewModel.newsList.observe(this, Observer { newsList -> // 更新视图 }) viewModel.loadNews("tech") } } ``` 通过使用 Kotlin + 协程 + Retrofit + MVVM,我们可以实现优雅地网络请求,代码简洁易懂,逻辑清晰。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流星雨在线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值