LiveData
ViewModel
- 添加依赖
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.501"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.327" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.501"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.499" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.151" />
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.154"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4"
app:srcCompat="@android:drawable/btn_star_big_off" />
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.853"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4"
app:srcCompat="@android:drawable/btn_star_big_on" />
</LinearLayout>
- MyViewModel.java
package com.example.myviewmodel;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
public int count;
}
- MainActivity.java
package com.example.myviewmodel;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btn1, btn2;
private TextView tv;
MyViewModel myViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
btn1 = findViewById(R.id.btn1);
btn2 = findViewById(R.id.btn2);
tv = findViewById(R.id.textView);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.count++;
tv.setText(String.valueOf(myViewModel.count));
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.count += 2;
tv.setText(String.valueOf(myViewModel.count));
}
});
}
}
保存状态

使viewmodel存活到系统配置改变,后台进程被杀死。但系统重新启动后,viewmodel也会重新创建,数据就没了。
打开虚拟机开发者模式,在开发者选项中app一栏,打开dont keep activities,可以模拟viewmodel被杀死。点击home按键,再返回app,数据还在。
添加依赖
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="data"
type="com.example.myviewmodelrestore.MyViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(data.getNumber)}"/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="@{()->data.add()}"/>
</LinearLayout>
</layout>
- MyViewModel.java
package com.example.myviewmodelrestore;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
private SavedStateHandle handle;
public MyViewModel(SavedStateHandle handle){
if (!handle.contains(MainActivity.KEY_NUMBER)){
handle.set(MainActivity.KEY_NUMBER, 0); // 设置一个初始值
}
this.handle = handle;
}
public MutableLiveData<Integer> getNumber() {
return handle.getLiveData(MainActivity.KEY_NUMBER);
}
public void add(){
handle.set(MainActivity.KEY_NUMBER, (int) handle.get(MainActivity.KEY_NUMBER) + 1);
}
}
- MainActivity.java
package com.example.myviewmodelrestore;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
import com.example.myviewmodelrestore.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
MyViewModel myViewModel;
ActivityMainBinding binding;
final static String KEY_NUMBER = "my_number";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
}
}
ViewModel访问全局资源

- 添加依赖
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
- 添加dataBinding
dataBinding.enabled true
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.example.myviewmodelsp.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(data.getNumber())}"
android:textSize="48sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="100" />
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_add"
android:onClick="@{()->data.add(1)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.264"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.582" />
<Button
android:id="@+id/btn_minus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_minus"
android:onClick="@{()->data.add(-1)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.735"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.582" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
- MyViewModel.java
package com.example.myviewmodelsp;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends AndroidViewModel { // 继承AndroidViewModel,可以直接使用getApplication()
SavedStateHandle handle;
String key = getApplication().getResources().getString(R.string.data_key);
String spName = getApplication().getResources().getString(R.string.sp_name);
public MyViewModel(@NonNull Application application, SavedStateHandle handle) {
super(application);
this.handle = handle;
// 如果handle里没有数据,就从sharedPreferences中取出
if (!handle.contains(key)){
load();
}
}
public LiveData<Integer> getNumber(){
return handle.getLiveData(key);
}
private void load(){
// 从sharedPreferences中取出数据存到savedStateHandle中
SharedPreferences sp = getApplication().getSharedPreferences(spName, Context.MODE_PRIVATE);
int x = sp.getInt(key, 0);
handle.set(key, x);
}
public void save(){
SharedPreferences sp = getApplication().getSharedPreferences(spName, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt(key, getNumber().getValue());
editor.apply();
}
public void add(int x){
handle.set(key, getNumber().getValue() + x);
// save();
}
}
- MainActivity.java
package com.example.myviewmodelsp;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle;
import com.example.myviewmodelsp.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
MyViewModel myViewModel;
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
}
@Override
protected void onPause() {
super.onPause();
myViewModel.save();
}
}
LiveData的更多相关文章
- 【安卓进阶】LiveData
最近参与到后端的工作中,虽然以前在工作中使用过PHP,但是这次使用的是Java,开发思路和方式有所不同.后端开发中,做接口也是需要处理大量的业务逻辑关系,同时一些事务之类的技术因素也要考虑好,在架设项 ...
- Android LiveData使用
LiveData是一个可观察的数据持有者类. 与常规observable不同,LiveData是生命周期感知的,当生命周期处于STARTED或RESUMED状态,则LiveData会将其视为活动状态, ...
- Jetpack 架构组件 LiveData ViewModel MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android官方架构组件介绍之LiveData
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
- Android官方架构组件介绍之LiveData(二)
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
- 【Android】ViewModel+LiveData:更加直接地控制视图的方式
目录 LiveData 前言 使用ViewModel+LiveData LiveData 前言 ViewModel通过将UI data保存在ViewModel类实例的内部,从而大大地将MVC中的 ...
- Jetpack系列:LiveData入门级使用方法
Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程.Google针对这一开发需求,提供了Jetpack LiveDat ...
- 【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式
原文作者: Jose Alcérreca 原文地址: ViewModels and LiveData: Patterns + AntiPatterns 译者:秉心说 View 和 ViewModel ...
- Android框架式编程之LiveData
一.LiveData 介绍 LiveData是 Google 推荐的 Android 架构组件之一,是一个基于观察者模式的数据容器,但与一般的被观察者不同的是,它是有生命周期感知功能,解决了Andro ...
- LiveData使用
### Andorid LiveData 使用 [[_TOC_]] #### Lifycycle 使用1.继承FragmentActivity 实现LifecycleOwner接口2.声明一个Life ...
随机推荐
- pytest中文文档
在网上找到的感觉还不错的pytest的中文文档,这里收藏一下: 翻译的中文文档:完整的Pytest文档 中文文档链接地址: https://www.osgeo.cn/pytest/contents.h ...
- java Hutool工具类之Excel的操作
1.背景 程序中上传下载excel是家常便饭,因此hutool给我们提供了非充强大的工具类,使用如下...... 2.使用 官方地址:https://hutool.cn/docs/#/poi/Exce ...
- 一文带你理解URI 和 URL 有什么区别?
当我们打开浏览器,要访问一个网站或者一个ftp服务器的时候,一定要输入一串字符串, 比如: https://blog.csdn.net/ 或者: ftp://192.168.0.111/ 这样我们就可 ...
- UVA11367 Full Tank?
优先队列bfs 1 #include<cmath> 2 #include<queue> 3 #include<cstdio> 4 #include<strin ...
- 题解:SP22382 ETFD - Euler Totient Function Depth
题目链接: link,点击这里喵. 前置知识: [模板]线性筛素数,欧拉函数,点击这里喵. 题意简述: 给定整数 $l,r,k$,求出 $[l,r]$ 中有多少个整数不断对自己取欧拉函数刚好 $k$ ...
- 查看 Homebrew 管理的服务的日志
TL;DR 首先找到 log 文件的位置: 对于 macOS (arm64),log 文件在 /opt/homebrew/var/log 目录下 对于 macOS (x86_64),log 文件在 / ...
- C#整合Ollama实现本地LLMs调用
前言 近两年AIGC发展的非常迅速,从刚开始的只有ChatGPT到现在的很百家争鸣.从开始的大参数模型,再到后来的小参数模型,从一开始单一的文本模型到现在的多模态模型等等.随着一起进步的不仅仅是模型的 ...
- Identity – Custom Entity
扩展属性 Custom Entity 指的是我们想对 Identity 的几个 Entity 做修改. 比如 User 要多一些 property, 或者 Id 用 int 而不是默认的 GUID. ...
- socket close和shutdown的区别,TIME_WAIT和CLOSE_WAIT
TCP主动关闭连接 appl: close(), --> FIN FIN_WAIT_1 //主动关闭socket方,调用close关闭socket,发FIN < ...
- Task2 - IDA学习【进度 - 第二课】
学习目标: - 无名侠的课,看二进制培训(第二集和第三集)(https://space.bilibili.com/7761039/video) - 会反汇编 - 会字符串搜索(f12) - 会简单异或 ...