Kotlin 用Retrofit+OkHttp+协程+LiveData搭建MVVM(Jetpack)来实现网络请求(网络数据JSON解析)显示在RecyclerView(更新中)

Posted 彬sir哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 用Retrofit+OkHttp+协程+LiveData搭建MVVM(Jetpack)来实现网络请求(网络数据JSON解析)显示在RecyclerView(更新中)相关的知识,希望对你有一定的参考价值。

文章目录

一、效果图

二、项目

三、添加依赖包

    //网络库
    implementation 'com.squareup.retrofit2:converter-gson:2.8.1'
    implementation 'com.squareup.retrofit2:retrofit:2.8.1'
    //网络
    implementation 'com.squareup.okhttp3:okhttp:4.2.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.2.0'
    //
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-rc02'
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0-rc02'
    implementation 'androidx.lifecycle:lifecycle-livedata:2.2.0-rc02'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc02'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-rc02'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-rc02'

四、Retrofit封装类

class RetrofitFactory private constructor() 
    private val retrofit: Retrofit

    init 
        val gson = Gson().newBuilder()
            .setLenient()
            .serializeNulls()
            .create()
        retrofit = Retrofit.Builder()
            .baseUrl("https://www.wanandroid.com/")
            .client(initOkhttpClient())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    

    companion object 
        val instance: RetrofitFactory by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) 
            RetrofitFactory()
        
    

    private fun initOkhttpClient(): OkHttpClient 
        val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .addInterceptor(initLogInterceptor())
            .build()
        return okHttpClient
    

    /*
    * 日志拦截器
    * */
    private fun initLogInterceptor(): HttpLoggingInterceptor 
        val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger 
            override fun log(message: String) 
                Log.i("Retrofit", message)
            
        )
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        return interceptor
    

    /*
    * 具体服务实例化
    * */
    fun <T> getService(service: Class<T>): T 
        return retrofit.create(service)
    

五、网络相关数据结构

1、返回数据最外层包装

data class Result<T>(
    val code: Int,
    val errorMsg: String?,
    val data: T
)
data class PageEntity<T>(
    val curPage:Int,
    val offset:Int,
    val over:Boolean,
    val size:Int,
    val PageCount:Int,
    val total:Int,
    val datas:List<T>
)

2、单个数据结构

class Article(
    @SerializedName("desc")
    val desc: String,
    @SerializedName("id")
    val id: Int,
    @SerializedName("title")
    val title: String,
)

六、定义协程api

interface ApiService 
    /**
     * 使用协程进行网络请求
     */
    @GET("article/list/page/json")
    suspend fun getArticleList(@Path("page") page: Int = 0): Result<PageEntity<Article>>

@GET(“article/list/page/json”),注意:page中的表示值是多少
这代码中,完整的https://www.wanandroid.com/article/list/1/json,点击这链接如下图:

七、ViewModel层

class ArticleViewModel : ViewModel() 
    private val _articleListData = MutableLiveData<List<Article>>()

    //保证外部只能观察此数据,不同通过setValue修改 model调用articleListData拿到网络请求数据交个观察者,但是不能修改
    val articleListData: LiveData<List<Article>> = _articleListData

    private val _errorMsg = MutableLiveData<String?>()
    val errorMsg: LiveData<String?> = _errorMsg

    fun fetch(page: Int) 
        viewModelScope.launch 
            var result = RetrofitFactory.instance.getService(ApiService::class.java).getArticleList(page)
            //请求到的数据用livedata包裹
            _articleListData.value = result.data.datas
        
    

八、UI层调用

class ArticleActivity : AppCompatActivity() 
    private val adapter by lazy 
        ArticleAdapter()
    
    lateinit var viewModel: ArticleViewModel
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view_model)
        viewModel = ArticleViewModel()
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
        recyclerView.adapter = adapter
        //观察文章列表数据
        viewModel.articleListData.observe(this, Observer  list ->
            //articleListData 的值改变时触发此监听
            loadProgress.visibility = View.GONE
            adapter.submitList(list)
        )
        viewModel.errorMsg.observe(this, Observer 
            if (it != null) 
//                toast(it)
                Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
            
        )
        btn.setOnClickListener 
            loadProgress.visibility = View.VISIBLE
            viewModel.fetch(1) //请求数据
        
    

九、旋转屏幕后数据的问题

旋转屏幕后数据丢失了,如下图:

解决,ArticleActivity.kt代码中:

viewModel = ArticleViewModel()

改为:

viewModel = ViewModelProvider(this).get(ArticleViewModel::class.java)

发现旋转屏幕后数据不会丢失了,如下图:

十、下载源码github地址

Kotlin 用Retrofit+OkHttp+协程+LiveData搭建MVVM(Jetpack)来实现网络请求(网络数据JSON解析)显示在RecyclerView

以上是关于Kotlin 用Retrofit+OkHttp+协程+LiveData搭建MVVM(Jetpack)来实现网络请求(网络数据JSON解析)显示在RecyclerView(更新中)的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 使用协程处理改造请求

使用Retrofit+Okhttp+LiveData+协程的MVVM实现的网络请求框架

使用Retrofit+Okhttp+LiveData+协程的MVVM实现的网络请求框架

OkHttp 和 Retrofit,用并发请求刷新令牌

两种方式封装Retrofit+协程,实现优雅快速的网络请求

两种方式封装Retrofit+协程,实现优雅快速的网络请求