文章目录
一、效果图

二、项目
三、添加依赖包
//网络库
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