AndroidMVVM架构Demo(kotlin+databinding+livedata。。。
MVVM优势
主要解决的问题:
⾼度解耦
解决了⽣命周期问题导致的内存泄漏
解决了mvp中的⼤量接⼝
MVVM的分层
View层就是展⽰数据的,以及接收到⽤户的操作传递给viewModel层,通过dataBinding实现数据与view的单向绑定或双向绑定Model层最重要的作⽤就是获取数据。(由于使⽤了协程所以不需要通过接⼝回调数据)
ViewModel 层通过调⽤model层获取数据,以及业务逻辑的处理。
MVVM中 viewModel 和MVP中的presenter 的作⽤类似 ,只不过是通过 databinding 将数据与ui进⾏了绑定。livedata⽤来通知数据的更新。
V层(activity+xml布局,主要负责UI的显⽰和交互)
package jetpack
t.Context
t.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import jetpack.databinding.ActivityMain3Binding
import jetpack.vm.Main3ViewModel
utines.Job
utines.launch
private const val TAG ="MainActivity3"
class Main3Activity :AppCompatActivity(){
companion object{
@JvmStatic
fun start(context: Context){
val starter =Intent(context, Main3Activity::class.java)
context.startActivity(starter)
}
}
private val viewModel by viewModels<Main3ViewModel>{Main3ViewModelFactory()}
private lateinit var binding: ActivityMain3Binding
private var searchJob: Job?=null
override fun onCreate(savedInstanceState: Bundle?){
//viewModel的直接创建⽅式(不推荐)
//viewModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory(application)).get(Main3ViewModel::class.java) //viewModel的另⼀种创建⽅式(Android Studio Demo中的⽅式)
//viewModel = ViewModelProvider(this).get(BlankViewModel::class.java)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main3)
binding.lifecycleOwner =this
binding.viewModel = viewModel
searchArticle()
}
fun onClick(view: View){
when(view){
binding.ivImg ->{
searchArticle()
}
}
}
private fun searchArticle(){
searchJob?.cancel()
searchJob = lifecycleScope.launch{
viewModel.searchArticle2()
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout android="schemas.android/apk/res/android"> <data>
<variable
name="viewModel"
type="jetpack.vm.Main3ViewModel"/>
</data>
<TextView
id="@+id/tv_test"
layout_width="match_parent"
layout_height="match_parent"
gravity="center"
onClick="onClick"
text="@{(0).url}"/>
</layout>
VM层(从M层获取数据,处理业务逻辑)
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import jetpack.bean.Article
import jetpack.data.ArticleRepository
import jetpack.data.ArticleRepositoryProvider
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
private const val TAG ="Main3ViewModel"
class Main3ViewModel(private val articleRepository: ArticleRepository):ViewModel(){ var liveData: MutableLiveData<Article>=MutableLiveData()
//协程,同步⽅式
suspend fun searchArticle2(){
liveData.value = articleRepository.searchRandomData2()
Log.d(TAG,"searchArticle2: "+ liveData.value?.results)
}
//线程,异步⽅式,通过接⼝回调数据
fun searchArticle3(){
articleRepository.searchRandomData3().enqueue(object: Callback<Article>{ override fun onFailure(call: Call<Article>, t: Throwable){
Log.e(TAG,"onFailure: "+ t.message)
}
override fun onResponse(call: Call<Article>, response: Response<Article>){                liveData.value = response.body()
}
})
}
}
class Main3ViewModelFactory : ViewModelProvider.Factory{
override fun<T : ViewModel?>create(modelClass: Class<T>): T {
return Instance())as T
}
}
M层(获取数据)
import jetpack.api.ArticleService
import jetpack.bean.Article
import jetpack.utils.RetrofitUtil
android retrofit
import retrofit2.Call
private const val TAG ="ArticleRepository"
interface ArticleRepository {
suspend fun searchRandomData2(): Article
fun searchRandomData3(): Call<Article>
}
private class ArticleRepositoryImpl(private val articleService: ArticleService): ArticleRepository {
//协程+Retrofit,同步⽅式
override suspend fun searchRandomData2(): Article {
return try{
}catch(e: Exception){
Log.e(TAG,"searchRandomData2: "+ e.message)
Article(true,null)
}
}
//线程+Retrofit,异步
override fun searchRandomData3(): Call<Article>{
RandomArticle3("福利","10")
}
}
object ArticleRepositoryProvider {
fun getInstance(): ArticleRepository {
return ArticleRepositoryImpl(RetrofitUtil.provide(ArticleService::class.java))
}
}
interface ArticleService {
/**
* 数据类型:福利 | Android | iOS | 休息视频 | 拓展资源 | 前端
* 个数:数字,⼤于0
*/
//协程+Retrofit,同步⽅式
@GET("api/random/data/{type}/{size}")
suspend fun getRandomArticle2(@Path("type") type: String?,@Path("size") size: String?): Article
//线程+Retrofit,异步
@GET("api/random/data/{type}/{size}")
fun getRandomArticle3(@Path("type") type: String?,@Path("size") size: String?): Call<Article> }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。