我是靠谱客的博主 爱笑铃铛,这篇文章主要介绍Android ViewModel使用Jetpack ViewModel,现在分享给大家,希望可以做个参考。

文章目录

  • Jetpack ViewModel
    • 概述
    • 添加依赖库
    • ViewModel的生命周期
    • 基本使用
      • AndroidViewModel
    • Fragment之间共享数据
    • ViewModel与onSaveInstanceState()区别
    • 代码下载

Jetpack ViewModel

概述

ViewModel 类目的在于以注重生命周期的方式存储和管理界面相关数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续留存。

添加依赖库

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
//ktx implementation "androidx.activity:activity-ktx:1.2.3" implementation "androidx.fragment:fragment-ktx:1.3.6" //Lifecycle def lifecycle_version = "2.5.0" //LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version" //ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"

ViewModel的生命周期

ViewModel 对象存在的时间范围是获取 ViewModel 时传递给 ViewModelProvider 的 LifecycleViewModel 将一直留在内存中,直到限定其存在时间范围的 Lifecycle 永久消失:对于 Activity,是在 Activity 完成时;而对于 Fragment,是在 Fragment 分离时。

由于ViewModel的生命周期长于Activity,因此不能将View或者Activity的context传给ViewModel,否则会引起内存泄露。

在这里插入图片描述

基本使用

在这里插入图片描述

在这里插入图片描述

ViewModel类实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyViewModel : ViewModel() { private val _countLiveData = MutableLiveData<Int>() val countLiveData = _countLiveData private var count = 0 fun increase() { _countLiveData.postValue(++count) } fun decrease() { _countLiveData.postValue(--count) } }

获取ViewModel对象,方式一

复制代码
1
2
var viewModel: MyViewModel = ViewModelProvider(this).get(MyViewModel::class.java)

获取ViewModel对象,方式二

复制代码
1
2
val viewModel: MyViewModel by viewModels()

在Activity中使用

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class ViewModelSimpleActivity : BaseActivity() { private lateinit var tvCount: TextView private lateinit var tvScreen: TextView private val viewModel: MyViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_view_model_simple) Log.e(VIEWMODEL, "onCreate") initView() val screenOrientation = if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) "竖屏" else "横屏" tvScreen.text = "屏幕方向:$screenOrientation" viewModel.countLiveData.observe(this, object : Observer<Int> { override fun onChanged(t: Int?) { Log.e(VIEWMODEL, "onChanged") tvCount.text = t.toString() } }) } private fun initView() { tvCount = findViewById(R.id.tv_count) tvScreen = findViewById(R.id.tv_screen) } fun clickIncrease(v: View) { viewModel.increase() } fun clickDecrease(v: View) { viewModel.decrease() } override fun onDestroy() { super.onDestroy() Log.e(VIEWMODEL, "onDestroy") } }

AndroidViewModel

因为ViewModel对象的存活时间较长,因此不能将Activity的Context传递给ViewModel,否则会引起内存泄露。如果需要使用context,这时可以使用AndroidViewModel接收Application的对象。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyAndroidViewModel(application: Application) : AndroidViewModel(application) { private val _countLiveData = MutableLiveData<Int>() val countLiveData = _countLiveData private var count = 0 fun increase() { _countLiveData.postValue(++count) } fun decrease() { _countLiveData.postValue(--count) } }

Fragment之间共享数据

优点:

  • Activity不需要做其他操作
  • Fragment之间没有任何干扰,只需要约定ViewModel

在这里插入图片描述

SharedViewModel类

复制代码
1
2
3
4
5
6
7
8
9
class SharedViewModel : ViewModel() { private val _liveData = MutableLiveData<String>() val liveData = _liveData fun select(item: String) { _liveData.postValue("$item detail") } }

Activity类

复制代码
1
2
3
4
5
6
7
8
9
10
11
class MenuActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_menu) supportFragmentManager.beginTransaction() .add(R.id.fl_menu, MenuFragment.newInstance()) .add(R.id.fl_detail, DetailFragment.newInstance()) .commit() } }

MenuFragment

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class MenuFragment : BaseFragment() { private val sharedViewModel: SharedViewModel by activityViewModels() companion object { fun newInstance() = MenuFragment() } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_menu, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val listView = view.findViewById<ListView>(R.id.listView) val data = ArrayList<String>().apply { for (i in 0..20) { add("menu$i") } } listView.adapter = ArrayAdapter(mContext, android.R.layout.simple_list_item_1, data) listView.setOnItemClickListener { parent, view, position, id -> sharedViewModel.select(data[position]) } } }

DetailFragment

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class DetailFragment : BaseFragment() { private val sharedViewModel: SharedViewModel by activityViewModels() companion object { fun newInstance() = DetailFragment() } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.detail_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val textView = view.findViewById<TextView>(R.id.textView) sharedViewModel.liveData.observe(viewLifecycleOwner, object : Observer<String> { override fun onChanged(t: String?) { textView.text = t } }) } }

ViewModel与onSaveInstanceState()区别

  • ViewModel:适用于配置变更导致的数据恢复,这是因为内存容量相对较大,可以存储较多的数据。
  • onSaveInstanceState():适用于被系统回收后重建时的数据恢复,这是因为系统回收时应用进程会消亡,因此不能用内存存储而是使用持久化存储,同时这部分数据需要通过Bundle机制传输数据,Bundle缓冲区有大小限制,只能适用于小规模数据。
ViewModelonSaveInstanceState()
存储方式在内存中序列化在磁盘
读写效率高(内存中访问)较慢(需要序列化、反序列化操作)
配置更改后,数据是否留存
系统回收后,数据是否留存
使用场景屏幕旋转等配置更改后保存Activity异常销毁时才会被调用
存储限制可存储复杂数据,存储大小受App可用内存影响只能存储可序列化对象,有存储大小有限制(一般为1M)

代码下载

最后

以上就是爱笑铃铛最近收集整理的关于Android ViewModel使用Jetpack ViewModel的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部