导入依赖
//认准extensions
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
简单使用:
创建一个ViewModel,直接继承
class MainViewModel : ViewModel() {
var counter = 0
}
使用:
class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
butAdd.setOnClickListener {
viewModel.counter++
tvNum.text=viewModel.counter.toString()
}
tvNum.text=viewModel.counter.toString()
}
}
这里获取viewmodel实例的方法是通过
ViewModelProviders.of(this).get(MainViewModel::class.java)
版本问题这里已经过时了,然而我搜的最新版本竟然已经去掉了这个方法......
因为ViewModel 的有自己独立的生命周期,并且生命周期要长于Activity,如果通过new ()来创建的话,那么内存泄露是一方面,另外当屏幕旋转或其他导致屏幕重新创建,就不能保存当前的状态了....
如何传递参数:
由于获取方式不是 new ,所以通过构造方法传递参数是个问题
ViewModelProvider.Factory
class MainViewModelFactory(private val countReversed: Int) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return MainViewModel(countReversed) as T
}
}
App退出之后重新打开,状态会重置,利用Sp
class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
lateinit var sp: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 获取Sp 实例
sp = getPreferences(Context.MODE_PRIVATE)
val count_reserved = sp.getInt("count_reserved", 0)
viewModel = ViewModelProviders.of(this,MainViewModelFactory(count_reserved)).get(MainViewModel::class.java)
butAdd.setOnClickListener {
viewModel.counter++
tvNum.text = viewModel.counter.toString()
}
butClear.setOnClickListener {
viewModel.counter = 0
tvNum.text = viewModel.counter.toString()
}
tvNum.text = viewModel.counter.toString()
}
override fun onPause() {
super.onPause()
sp.edit {
putInt("count_reserved",viewModel.counter)
}
}
}
这里我在使用sp.edit{}时.出现了please specify proper '-jvm',需要在builkd.gradle里添加
//新增如下配置
kotlinOptions {
jvmTarget = "1.8"
}
可以在一个非Activity 的 类中去感知Activity 的生命周期.
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun activityStart() {
println(" activityStart ")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun activityStop() {
println(" activityStop ")
}
}
可以看到是通过注解的方式
在Activity里边进行添加就可以了
]lifecycle.addObserver(MyObserver())
主动获取状态
class MyObserver(val lifecycle: Lifecycle) : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun activityStart() {
val currentState = lifecycle.currentState
println(" currentState :" + currentState)
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun activityStop() {
println(" activityStop ")
}
}
lifecycle.addObserver(MyObserver(lifecycle))
响应式编程,一种高级的观察者模式
结合ViewModel 的一个例子:
class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainViewModel
lateinit var sp: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sp = getPreferences(Context.MODE_PRIVATE)
val count_reserved = sp.getInt("count_reserved", 0)
viewModel = ViewModelProviders.of(this, MainViewModelFactory(count_reserved))
.get(MainViewModel::class.java)
butAdd.setOnClickListener {
viewModel.add()
}
butClear.setOnClickListener {
viewModel.clear()
}
viewModel.counter.observe(this, Observer {
tvNum.text = it.toString()
})
}
override fun onPause() {
super.onPause()
sp.edit {
putInt("count_reserved", viewModel.counter.value ?: 0)
}
}
}
class MainViewModel(countReserved: Int) : ViewModel() {
// Mitable 为可变的
val counter = MutableLiveData()
init {
counter.value = countReserved
}
/**
* 加1
*/
fun add() {
//意思是默认为0 如果 对象是空的? 则:为0
val count = counter.value ?: 0
counter.value = count + 1
}
/**
* 清零
*/
fun clear() {
counter.value = 0
}
}
class MainViewModelFactory(private val countReversed: Int) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
return MainViewModel(countReversed) as T
}
}
效果不变
这里只有一个Int,
可以自定义个Bean
这里换成子线程里进行.value 就报错了
换成postValue() 就可以了
然后作者又写了一个规范写法 :.....我指定是不懂的
class MainViewModel(countReserved: Int) : ViewModel() {
// Mitable 为可变的
val counter : LiveData
get() = _counter
private val _counter =MutableLiveData()
init {
_counter.value = countReserved
}
/**
* 加1
*/
fun add() {
Thread() {
//意思是默认为0 如果 对象是空的? 则:为0
val count = counter.value ?: 0
_counter.postValue( count + 1)
}
.start()
}
/**
* 清零
*/
fun clear() {
_counter.value = 0
}
}
照着粘把.....
map 和 switchMap
主要是为了防止暴露