当前位置: 首页 > 编程日记 > 正文

Android笔记之ViewModel的使用示例

依赖

implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

android.arch.lifecycle:extensions:1.1.1用于引用ViewModelProviders

ViewModelProviders官方文档

EyeKeyService.java

package com.bu_ish.viewmodeltest.service;import com.bu_ish.viewmodeltest.reply.FaceCheckingReply;
import com.bu_ish.viewmodeltest.reply.FacesComparingReply;import io.reactivex.Single;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;public interface EyeKeyService {String BASE_URL = "http://api.eyekey.com/face/";String APP_ID = "f89ae61fd63d4a63842277e9144a6bd2";String APP_KEY = "af1cd33549c54b27ae24aeb041865da2";@FormUrlEncoded@POST("Check/checking")Single<FaceCheckingReply> checkFace(@Field("app_id") String appId, @Field("app_key") String appKey, @Field("url") String url);@GET("Match/match_compare")Single<FacesComparingReply> compareFaces(@Query("app_id") String appId, @Query("app_key") String appKey, @Query("face_id1") String faceId1, @Query("face_id2") String faceId2);
}

EyeKeyRepository.java

package com.bu_ish.viewmodeltest.view_model;import com.bu_ish.viewmodeltest.service.EyeKeyService;
import com.bu_ish.viewmodeltest.reply.FaceCheckingReply;
import com.bu_ish.viewmodeltest.reply.FacesComparingReply;import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;public class EyeKeyRepository {private static EyeKeyRepository instance = new EyeKeyRepository();private EyeKeyService service;private EyeKeyRepository() {Retrofit retrofit = new Retrofit.Builder().baseUrl(EyeKeyService.BASE_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();service = retrofit.create(EyeKeyService.class);}public static EyeKeyRepository getInstance() {return instance;}public Single<FaceCheckingReply> checkFace(String url) {return setScheduler(service.checkFace(EyeKeyService.APP_ID, EyeKeyService.APP_KEY, url));}public Single<FacesComparingReply> compareFaces(String faceId1, String faceId2) {return setScheduler(service.compareFaces(EyeKeyService.APP_ID, EyeKeyService.APP_KEY, faceId1, faceId2));}private Single setScheduler(Single single) {return single.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());}
}

EyeKeyViewModel.java

package com.bu_ish.viewmodeltest.view_model;import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;import com.bu_ish.viewmodeltest.observer.ReplyObserver;
import com.bu_ish.viewmodeltest.reply.FaceCheckingReply;
import com.bu_ish.viewmodeltest.reply.FacesComparingReply;public class EyeKeyViewModel extends ViewModel {public MutableLiveData<FaceCheckingReply> faceCheckingReply1Data = new MutableLiveData<>();public MutableLiveData<FaceCheckingReply> faceCheckingReply2Data = new MutableLiveData<>();public MutableLiveData<FacesComparingReply> facesComparingReplyData = new MutableLiveData<>();private DialogViewModel dialogViewModel;private EyeKeyRepository eyeKeyRepository;public EyeKeyViewModel(DialogViewModel dialogViewModel) {this.dialogViewModel = dialogViewModel;eyeKeyRepository = EyeKeyRepository.getInstance();}public void checkFace1(String url) {eyeKeyRepository.checkFace(url).subscribe(new ReplyObserver<FaceCheckingReply>(dialogViewModel) {@Overridepublic void onReply(FaceCheckingReply reply) {faceCheckingReply1Data.setValue(reply);}});}public void checkFace2(String url) {eyeKeyRepository.checkFace(url).subscribe(new ReplyObserver<FaceCheckingReply>(dialogViewModel) {@Overridepublic void onReply(FaceCheckingReply reply) {faceCheckingReply2Data.setValue(reply);}});}public void compareFaces(String faceId1, String faceId2) {eyeKeyRepository.compareFaces(faceId1, faceId2).subscribe(new ReplyObserver<FacesComparingReply>(dialogViewModel) {@Overridepublic void onReply(FacesComparingReply reply) {facesComparingReplyData.setValue(reply);}});}
}

ReplyObserver.java

package com.bu_ish.viewmodeltest.observer;import com.bu_ish.viewmodeltest.reply.BaseReply;
import com.bu_ish.viewmodeltest.view_model.DialogViewModel;import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;public abstract class ReplyObserver<T extends BaseReply> implements SingleObserver<T> {public abstract void onReply(T reply);private DialogViewModel dialogViewModel;public ReplyObserver(DialogViewModel dialogViewModel) {this.dialogViewModel = dialogViewModel;}@Overridepublic void onSubscribe(Disposable d) {dialogViewModel.showProgressData.setValue(true);}@Overridepublic void onSuccess(T reply) {dialogViewModel.showProgressData.setValue(false);String code = reply.getResCode();if (code.equals("0000")) {onReply(reply);} else {dialogViewModel.showErrorData.setValue(reply);}}@Overridepublic void onError(Throwable e) {dialogViewModel.showProgressData.setValue(false);dialogViewModel.showExceptionData.setValue(e);}
}

EyeKeyViewModelFactory.java

package com.bu_ish.viewmodeltest.view_model;import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider;
import android.support.annotation.NonNull;public class EyeKeyViewModelFactory implements ViewModelProvider.Factory {private DialogViewModel dialogViewModel;public EyeKeyViewModelFactory(DialogViewModel dialogViewModel) {this.dialogViewModel = dialogViewModel;}@NonNull@Overridepublic <T extends ViewModel> T create(@NonNull Class<T> modelClass) {return (T) new EyeKeyViewModel(dialogViewModel);}
}

DialogViewModel.java

package com.bu_ish.viewmodeltest.view_model;import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;import com.bu_ish.viewmodeltest.reply.BaseReply;public class DialogViewModel extends ViewModel {public MutableLiveData<Boolean> showProgressData = new MutableLiveData<>();public MutableLiveData<BaseReply> showErrorData = new MutableLiveData<>();public MutableLiveData<Throwable> showExceptionData = new MutableLiveData<>();
}

使用ViewModel的好处

即使发生配置变更(Configuration Change),ViewModel中的数据依然存在

所以,使用ViewModel后,也就不需要考虑onSaveInstanceState这类操作了^_^

参考博文

MVVM 架构,ViewModel和LiveData(一)

完整Demo

链接:https://pan.baidu.com/s/1TwY9OZTaQPk1eCn7vSz4fA,提取码:x0fy

转载于:https://www.cnblogs.com/buyishi/p/10663895.html

相关文章:

vscode配置记录

vscode配置记录 按照官网教程安装好vs:实际上只需要配置launch.json的”program“如下所示 "configurations": [{"name": "(gdb) Launch","type": "cppdbg","request": "launch","program":…

unity 2d 游戏优化之路 遇坑记录

情景说明&#xff1a; unity 出的Android包&#xff0c;在目前一些主流机型跑都没有问题&#xff0c;但是在 小米3 这种比较老的机器上跑&#xff0c;报如下错误 GLSL compilation failed, no infolog provided 起先&#xff0c;我们一直以为是在低端机器上某个特定的GLSL 在这…

自定义直方图实现

#include <opencv2/opencv.hpp> int main() {// 图像获取及判断cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;cv::imshow("srcImage",srcImage);// 灰度转换 cv::Mat srcGray;cv::cvtColor(srcImage,sr…

js数组指定位置添加删除

示例参考&#xff1a;http://www.w3school.com.cn/jsref/jsref_splice.asp转载于:https://www.cnblogs.com/CarryYou-lky/p/10669859.html

【C++】对象实例化/成员函数/成员变量的内存管理

文章目录1. 对象实例化的内存管理总结2.C成员函数在内存中的存储方式3.C类的实例化对象的大小之sizeof()实例一&#xff1a;实例二&#xff1a;实例三&#xff1a;实例四&#xff1a;实例五&#xff1a;实例六&#xff1a;实例七&#xff1a;实例八&#xff1a;实例九&#xff…

HTML form 标签的 enctype 属性

1. enctype 的定义和用法 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。 默认地&#xff0c;表单数据会编码为 "application/x-www-form-urlencoded"。 就是说&#xff0c;在发送到服务器之前&#xff0c;所有字符都会进行编码&#xff08;空格转…

灰度直方图均衡化实现

#include <opencv2/opencv.hpp> int main() {cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;cv::Mat srcGray;cv::cvtColor(srcImage, srcGray, CV_BGR2GRAY);cv::imshow("srcGray", srcGray);// 直方图均…

oracle汉化包下载地址

2019独角兽企业重金招聘Python工程师标准>>> https://www.allroundautomations.com/bodyplsqldevreg.html 转载于:https://my.oschina.net/u/3141521/blog/3034655

【C++】C/C++ 中 static 的用法全局变量与局部变量

C/C 中 static 的用法全局变量与局部变量 目录 1. 什么是static? 1.1 static 的引入 1.2 静态数据的存储 2. 在 C/C 中static的作用 2.1 总的来说 2.2 静态变量与普通变量 2.3 静态局部变量有以下特点&#xff1a; 实例 3. static 用法 3.1 在 C 中 3.2 静态类相关…

浅谈C/C++中的static和extern关键字

一.C语言中的static关键字 在C语言中&#xff0c;static可以用来修饰局部变量&#xff0c;全局变量以及函数。在不同的情况下static的作用不尽相同。 (1)修饰局部变量 一般情况下&#xff0c;对于局部变量是存放在栈区的&#xff0c;并且局部变量的生命周期在该语句块执行结束时…

彩色直方图均衡化实现

#include <opencv2/opencv.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;// 存储彩色直方图及图像通道向量cv::Mat colorHeqImage; std::vector<cv::Mat> BGR_plane; …

二、python小功能记录——监听鼠标事件

1.原文链接 #-*- coding:utf-8 -*- from pynput.mouse import Button, Controller## ## 控制鼠标 ## # 读鼠标坐标 mouse Controller() print(The current pointer position is {0}.format(mouse.position)) # 设置鼠标坐标 mouse.position (10, 20) print(No…

【Smart_Point】C/C++ 中智能指针

C11智能指针 目录 C11智能指针 1.1 C11智能指针介绍 1.2 为什么要使用智能指针 1.2.1 auto_ptr&#xff08;C98的方案&#xff0c;C11已经抛弃&#xff09;采用所有权模式。 1.2.2 unique_ptr 1.2.3 shared_ptr 1.2.4 weak_ptr 1.3 share_ptr和weak_ptr的核心实现 1.…

Linux 虚拟内存和物理内存的理解【转】

转自:http://www.cnblogs.com/dyllove98/archive/2013/06/12/3132940.html 首先&#xff0c;让我们看下虚拟内存&#xff1a; 第一层理解 1. 每个进程都有自己独立的4G内存空间&#xff0c;各个进程的内存空间具有类似的结构 2. 一个新进程建立的时候&#xff0c…

直方图变换——查找

#include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;//…

【C++】C/C++ 中default/delete特性

C类的特殊成员函数及default/delete特性 本文内容侧重个人理解&#xff0c;深入理解其原理推荐https://www.geeksforgeeks.org 目录 目录 C类的特殊成员函数及default/delete特性 前言 1. 构造函数和拷贝构造函数 2. 拷贝赋值运算符 3. C11特性之default关键字(P237, P4…

Celery--任务调度利器

2019独角兽企业重金招聘Python工程师标准>>> Celery文档: http://docs.jinkan.org/docs/celery/getting-started/first-steps-with-celery.html 安装celery和celery-with-redis pip install Celery pip install celery-with-redis开始编写task.py # tasks.py import…

直方图变换——累计

#include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> int main() {// 图像获取及验证cv::Mat srcImage cv::imread("..\\images\\flower3.jpg");if( !srcImage.data ) return 1;//…

iOS开发经验总结,我的2019进阶之路!

4G改变了生活&#xff0c;抓住机会的人已经在这个社会有了立足之地&#xff0c;马上迎来5G的时代&#xff0c;你做好准备了吗&#xff01;对于即将迎来的5G时代&#xff0c;无疑会是音视频的又一个高潮&#xff01;那么作为程序员的我们&#xff0c;应该怎么样去迎接它呢~~ 改变…

【C++】C/C++ 中多态情形下的虚函数表查看方法

1.查看工具 找到VS2017命令提示符工具 选择“VS 2017的开发人员命令提示符” 点击该选项栏&#xff0c;弹出“VS 2017的开发人员命令提示符”窗口 cd 控制进入带查看类躲在的位置 使用命令&#xff1a;cl /d1 reportSingleClassLayoutXXX [filename]&#xff0c;XXX表示类名&…

PHP中session_register函数详解用法

语法: boolean session_register(string name);注册新的变量。返回值: 布尔值函数种类: 资料处理内容说明本函数在全域变量中增加一个变量到目前的 Session 之中。参数 name 即为欲加入的变量名。成功则返回 true 值。假如在头文件&#xff0c;开启session,即使用session_start…

Fedora 提出统一流程,弃用上千 Python 2 软件包更可控

开发四年只会写业务代码&#xff0c;分布式高并发都不会还做程序员&#xff1f; >>> Fedora 社区正在讨论弃用 Python 2 软件包的统一流程。 https://pythonclock.org Python 2 将于 2020 年 1 月 1 日正式退休&#xff0c;官方不再提供维护&#xff0c;当前倒计时不…

【C++】C++对象模型:对象内存布局详解(C#实例)

C对象模型&#xff1a;对象内存布局详解 0.前言 C对象的内存布局、虚表指针、虚基类指针解的探讨&#xff0c;参考。 1.何为C对象模型? 引用《深度探索C对象模型》这本书中的话&#xff1a; 有两个概念可以解释C对象模型&#xff1a; 语言中直接支持面向对象程序设计的部分…

Mybatis插件原理和PageHelper结合实战分页插件(七)

今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理。PageHelper的官方网站&#xff1a;https://github.com/pagehelper/Mybatis-PageHelper一、Plugin接口mybatis定义了一个插件接口org.apache.ibatis.plugin.Intercept…

直方图反向投影

#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace cv; using namespace std; int main() {// 加载源图像并验证cv::Mat srcImage cv::imread("..\\images\\hand1.jpg&quo…

Java异常处理12条军规

摘要&#xff1a; 简单实用的建议。 原文&#xff1a;Java异常处理12条军规公众号&#xff1a;Spring源码解析Fundebug经授权转载&#xff0c;版权归原作者所有。 在Java语言中&#xff0c;异常从使用方式上可以分为两大类&#xff1a; CheckedExceptionUncheckedException在Ja…

【Smart_Point】C/C++ 中独占指针unique_ptr

1. 独占指针unique_ptr 目录 1. 独占指针unique_ptr 1.1 unique_ptr含义 1.2 C11特性 1.3 C14特性 1.1 unique_ptr含义 unique_ptr 是 C 11 提供的用于防止内存泄漏的智能指针中的一种实现&#xff0c;独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指…

ORA-01940无法删除当前已连接用户

原文地址&#xff1a;ORA-01940无法删除当前已连接用户作者&#xff1a;17361887941)查看用户的连接状况 select username,sid,serial# from v$session ------------------------------------------ 如下结果&#xff1a; username sid serial# ------…

距离变换扫描实现

#include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> // 计算欧式距离 float calcEuclideanDistance(int x1, int y1, int x2, int y2) {return sqrt(…

『扩欧简单运用』

扩展欧几里得算法 顾名思义&#xff0c;扩欧就是扩展欧几里得算法&#xff0c;那么我们先来简单地回顾一下这个经典数论算法。 对于形如\(axbyc\)的不定方程&#xff0c;扩展欧几里得算法可以在\(O(log_2alog_2b)\)的时间内找到该方程的一组特解&#xff0c;或辅助\(gcd\)判断该…