前言
話說我真是怠惰啊,各種鴿蠢沿,寫jetpack又寫設(shè)計(jì)模式還寫個(gè)view恤磷,各種挖坑扫步,算了河胎,繼續(xù)慢慢填政敢,這次來聊下ViewModel
ViewModel
在Jetpcak里面,LifeCycles、ViewModel、LiveData這三個(gè)是相輔相成的灾馒,我個(gè)人的理解是ViewModel實(shí)現(xiàn)了LifeCycles的功能,也是有生命周期的感知的,而且它的生命周期更廣(比Activity還要廣)
也正因?yàn)槿绱斯阶Γ运步鉀Q了2個(gè)問題:
1.當(dāng)Activity/Fragment被銷毀重建時(shí)凳宙,成員變量被清空(需要用onSaveInstanceState()保存數(shù)據(jù)恢復(fù)什么的)
2.當(dāng)Activity/Fragment進(jìn)行異步操作時(shí)導(dǎo)致的內(nèi)存泄漏(雖然沒有直接解決,而是提供了onCleared()這個(gè)方法讓我們?nèi)ヌ幚恚?br> FBI WARNING
正是因?yàn)閂iewModel比Activity的生命周期還要長饺汹,所以ViewModel如果持有Activity的實(shí)例陨囊,那肯定要產(chǎn)生內(nèi)存泄漏的(如果業(yè)務(wù)需要蜘醋,使用AndroidViewModel(application))
導(dǎo)入
首先我們要依賴Google倉庫胎食,在project -> build.gradle里
repositories {
//一般來說自動(dòng)生成的項(xiàng)目都會(huì)默認(rèn)依賴Google和Jcenter倉庫的
google()
jcenter()
}
然后是Module -> build.gradle
dependencies {
def lifecycle_version = "2.0.0"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
// alternatively - just ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" // For Kotlin use lifecycle-viewmodel-ktx
// alternatively - just LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
// AndroidX libraries use this lightweight import for Lifecycle
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" // For Kotlin use kapt instead of annotationProcessor
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
}
看注釋按需導(dǎo)入
使用
簡單到爆炸的用法...
class MyViewModel : ViewModel(){
var name: String = "xiao"
}
在Activity里面調(diào)用
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val model = ViewModelProviders.of(this)[MyViewMode::class.java]
tv.text = model.name
}
}
可能會(huì)遇到的問題厕怜, ViewModelProviders.of(this)爆紅,這個(gè)一般是AndroidX的包引起的蕾总,將項(xiàng)目遷移至AndroidX就好了粥航,Refactor -> Migrate to AndroidX
Fragment共享
這個(gè)也是ViewModel解決的痛點(diǎn)之一,of方法里面不僅可以傳Activity對(duì)象生百,也可以傳Fragment對(duì)象递雀,所以在同Activity下的不同F(xiàn)ragment,我們可以傳入相同的Activity對(duì)象來獲得實(shí)例蚀浆,以此解決Fragment之間的通訊問題缀程。比起直接弄個(gè)全局靜態(tài)對(duì)象來通信算是好太多了
//FirstFragment
class FirstFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_first, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mode = activity?.let { ViewModelProviders.of(it).get(MyViewMode::class.java) }
text.text = mode.toString()
}
}
//SecondFragment
class SecondFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_second, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val mode = activity?.let { ViewModelProviders.of(it).get(MyViewMode::class.java) }
text.text = mode.toString()
}
}
可以看到2個(gè)Fragment拿到的是同一個(gè)對(duì)象
總結(jié)
ViewModel其實(shí)挺簡單的,在我的理解就是一個(gè)全局的靜態(tài)對(duì)象市俊,然后又有了生命周期杨凑,但其實(shí)它帶來的是一種新的思想,MVVM摆昧,也就是數(shù)據(jù)驅(qū)動(dòng)蠢甲,viewModel作為中樞,從數(shù)據(jù)庫獲取數(shù)據(jù)据忘,然后交由liveData通知UI更新,關(guān)于liveData搞糕,我們下期見