依赖

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) {
@Override
public void onReply(FaceCheckingReply reply) {
faceCheckingReply1Data.setValue(reply);
}
});
} public void checkFace2(String url) {
eyeKeyRepository.checkFace(url).subscribe(new ReplyObserver<FaceCheckingReply>(dialogViewModel) {
@Override
public void onReply(FaceCheckingReply reply) {
faceCheckingReply2Data.setValue(reply);
}
});
} public void compareFaces(String faceId1, String faceId2) {
eyeKeyRepository.compareFaces(faceId1, faceId2).subscribe(new ReplyObserver<FacesComparingReply>(dialogViewModel) {
@Override
public 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;
} @Override
public void onSubscribe(Disposable d) {
dialogViewModel.showProgressData.setValue(true);
} @Override
public void onSuccess(T reply) {
dialogViewModel.showProgressData.setValue(false);
String code = reply.getResCode();
if (code.equals("0000")) {
onReply(reply);
} else {
dialogViewModel.showErrorData.setValue(reply);
}
} @Override
public 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
@Override
public <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

Android笔记之ViewModel的使用示例的更多相关文章

  1. Android笔记——Android中数据的存储方式(二)

    我们在实际开发中,有的时候需要储存或者备份比较复杂的数据.这些数据的特点是,内容多.结构大,比如短信备份等.我们知道SharedPreferences和Files(文本文件)储存这种数据会非常的没有效 ...

  2. Android笔记:触摸事件的分析与总结----TouchEvent处理机制

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://glblong.blog.51cto.com/3058613/1559320   ...

  3. [置顶] Xamarin android如何调用百度地图入门示例(一)

    在Xamarin android如何调用百度地图呢? 首先我们要区分清楚,百度地图这是一个广泛的概念,很多刚刚接触这个名词"百度地图api",的确是泛泛而谈,我们来看一下百度地图的 ...

  4. Android判断当前网络是否可用--示例代码

    Android判断当前网络是否可用--示例代码 分类: *07 Android 2011-05-24 13:46 7814人阅读 评论(4) 收藏 举报 网络androiddialogmanagern ...

  5. Android 笔记之 R 文件

    Android笔记之R文件 h2{ color: #4abcde; } a{ color: blue; text-decoration: none; } a:hover{ color: red; te ...

  6. Android 笔记之 Android 系统架构

    Android笔记之Android系统架构 h2{ color: #4abcde; } a{ color: blue; text-decoration: none; } a:hover{ color: ...

  7. Android笔记之使用Glide加载网络图片、下载图片

    Glide简介 不想说太多,真的很方便:P)可以节省我不少时间 GitHub地址:https://github.com/bumptech/glide 加载网络图片到ImageView Glide.wi ...

  8. Android笔记--View绘制流程源码分析(二)

    Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...

  9. Android笔记--View绘制流程源码分析(一)

    Android笔记--View绘制流程源码分析 View绘制之前框架流程分析 View绘制的分析始终是离不开Activity及其内部的Window的.在Activity的源码启动流程中,一并包含 着A ...

随机推荐

  1. Theam,style

    Theam <!-- Base application theme. --> <!--<style name="AppTheme" parent=" ...

  2. iphone/iOS 访问本地数据库sqlite3

    Phone也支持访问本地数据库Sqlite 3.这里简单的介绍一下iPhone上Sqlite 3的使用方法. 首先需要在项目中引用Sqlite 3的开发包,下面是在iPhone SDK 3.0下的目录 ...

  3. 200多种Android动画效果的强悍框架

    admin 发布于2015-10-23 14:33 363/68015 [精品推荐]200多种Android动画效果的强悍框架,太全了,不看这个,再有动画的问题,不理你了^@^ 功能模块和技术方案 只 ...

  4. EasyMvc入门教程-高级控件说明(17)对话框控件

    上一节我们说到的信息框比较简单,如果我们想简单实现用户用户交互,比如常用的锁屏界面,应该如何实现呢?首先看效果: 当用户输入"mxd",后,界面显示如下: 以上效果的实现代码为: ...

  5. ylb:日期和时间函数

    ylbtech-SQL Server:SQL Server-日期和时间函数 日期和时间函数. ylb:日期和时间函数 返回顶部 1,日期和时间函数获取(当前)日期 GetDate() 2,提取部分日期 ...

  6. softmax函数python实现

    import numpy as np def softmax(x): """ 对输入x的每一行计算softmax. 该函数对于输入是向量(将向量视为单独的行)或者矩阵(M ...

  7. Linux学习之十三-vi和vim编辑器及其快捷键

    vi和vim编辑器及其快捷键 1.vi与vim区别 它们都是多模式编辑器,不同的是vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面. vim的这些优势主要体现在以下几个方 ...

  8. 常见CSS两栏式布局

    代码下载:https://files.cnblogs.com/files/xiandedanteng/TwoColumnLayout.rar 效果展示: 代码: <!DOCTYPE html&g ...

  9. 有用PHP依赖管理工具Composer新手教程

    PHP依赖管理工具Composer新手教程 Composer 是 PHP 的一个依赖管理工具.它同意你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 依赖管理 Composer 不是一个包管理 ...

  10. StringBuilder作用

    String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然 ...