Kotlin 用Retrofit+OkHttp+协程+LiveData搭建MVVM(Jetpack)来实现网络请求显示在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) //请求数据
        }
    }
}

九、下载源码github地址

Kotlin+Retrofit+OkHttp+协程+LiveData+MVVM(Jetpack)实现网络请求显示在RecyclerView

猜你喜欢

转载自blog.csdn.net/qq_35091074/article/details/125973496