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 ...
随机推荐
- reinforcement learning常用的游戏环境,gym框架使用的标准Atari游戏集合
reinforcement learning常用的游戏环境,gym框架使用的标准Atari游戏集合.*.bin文件为Atari2600游戏的常用游戏环境的模拟文件,也称为roms文件. 文件地址: h ...
- 【转载】 MPP大规模并行处理架构详解
本文来自博客园,作者:五分钟学大数据 原文链接:https://www.cnblogs.com/itlz/p/14998858.html =============================== ...
- 文本相似度 HanPL汉语言处理
@ 目录 前言 需求 简介 实操开始 1. 添加pom.xml依赖 2. 文本相似度工具类 3. 案例验证 4. 验证结果 总结 前言 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i. 提示 ...
- 多线程之interrupt与优雅停止一个线程
1.背景 在实际开发中,我们可能会遇到终止某个线程的场景, 比如不断扫描数据库的发货订单时,这时候需停止扫描, 当然我们不能把程序关了,我们只希望停止扫描数据库这一个线程, 那么应该怎么办了? 这就可 ...
- [CEOI2011] Matching 题解
前言 题目链接:洛谷. 在上一题之后,模拟赛又放了一道 KMP 重定义相等的问题,但是寄了,故再记之. 题意简述 现在给出 \(1 \sim n\) 的排列 \(p\) 和序列 \(h_1, h_2, ...
- CryptoHouse:由 ClickHouse 和 Goldsky 支持的免费区块链分析服务(ClickHouse 博客)
我们很高兴地宣布 CryptoHouse,在 crypto.clickhouse.com 上可访问,这是一个由 ClickHouse 提供支持的免费区块链分析服务. https://crypto.cl ...
- [天线原理及设计>基本原理] 3. 辐射方向图或天线方向图
<Antenna_Theory_Analysis_and_Design_3rd_Constantine_A._Balanis.pdf> 3. 辐射方向图或天线方向图 天线辐射方向图或天线方 ...
- 2023 ICPC 杭州游记
题解 省流:三个 NOI 银牌合成一个 ICPC 区域赛银牌 感谢 gjy 的铜钱剑 和 hszx 的大家玩得很开心 两个联赛数据结构没做出来
- Camera | 1.Camera基础知识
一口君最近在玩瑞芯微的板子,之前写了几篇基于瑞芯微的文章,大家可以学习一下. <瑞芯微rk356x板子快速上手> <Linux驱动|rtc-hym8563移植笔记> <L ...
- Linux-centos中修改默认root帐户的登录用户名
vi /etc/passwd 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键退出编辑状态,并输入:x保存并退出 vi /etc/shadow 按i键进入编辑状态 修改第1行第1个 ...