基于Android RxCache使用方法详解

前言

我为什么使用这个库?

事实上Android开发中缓存功能的实现选择有很多种,File缓存,SP缓存,或者数据库缓存,当然还有一些简单的库/工具类,比如github上的这个:

【ASimpleCache】:a simple cache for android and java

但是都不是很好用(虽然可能学习成本比较低,因为它使用起来相对简单),我可能需要很多的静态常量来作为key存储缓存数据value,并设置缓存的有效期,这可能需要很多Java代码去实现,并且过程繁琐。

如果您使用的网络请求库是Retrofit+RxJava,那么我推荐使用RxCache,正如作者所说的:

RxCache is a reactive caching library for Android and Java which turns your caching needs into an interface.
RxCache是一个用于Android和Java的响应式缓存库,它可将您的缓存需求转换为一个接口。

为什么写这样一篇文章

因为这个库的官方文档是!英!语!的!

这本身无可厚非,作为一个开发者,英语文档的阅读是不可避免的一项技能,但是笔者还是抽了一点时间将官方文档做了汉化:

RxCache官方文档中文翻译

RxCache库官方链接

文档的翻译比想象中的费力(每一个词都试图翻译准确),但数小时的努力之后,译文的描述依然对于初次接触该库的开发者有着不小的学习难度,干脆自己写一个demo,并放到github上,供大家参考。

【Github】本文demo源码,点击进入

1.依赖配置

在您的build.gradle(Project)中添加JitPack仓库:

allprojects {
  repositories {
    jcenter()
    maven { url "https://jitpack.io" }
  }
}

将下列的依赖添加到Module的build.gradle中:

dependencies {
  compile "com.github.VictorAlbertos.RxCache:runtime:1.8.1-2.x"
  compile "io.reactivex.rxjava2:rxjava:2.0.6"
  //我们再添加这个依赖,下面有说明
  compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.3'
}

因为RxCache在内部使用 Jolyglot 对对象进行序列化和反序列化, 您需要选择下列的依赖中选择一个进行添加:

dependencies {
  // To use Gson
  compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.3'
  // To use Jackson
  compile 'com.github.VictorAlbertos.Jolyglot:jackson:0.0.3'
  // To use Moshi
  compile 'com.github.VictorAlbertos.Jolyglot:moshi:0.0.3'
}

2.Retrofit请求示例

我们假设这样一个需求,通过传入user名,返回User对应信息,比如:

Retrofit API接口

public interface GitHubService {
  @GET("users/{user}")
  Observable<User> getRxUser(@Path("user") String user);
}

该API请求的管理类ServiceManager

public class GitHubServiceManager {
  private GitHubService service;
  public GitHubServiceManager() {
    init();
  }
  private void init() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor()
        .setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient()
        .newBuilder()
        .addInterceptor(interceptor)
        .build();
    service = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(client)
        .build()
        .create(GitHubService.class);
  }
  public Observable<User> getUser(String user){
    return service.getRxUser(user);
  }
}

User数据类

@Data  //lombok插件的注解,自动生成get、set方法
public class User {
 public String login;
 public String name;
}

最后在我们的Activity中获取数据:

 new GitHubServiceManager()
        .getUser(userName)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(user1 -> Toast.makeText(this, user1.toString(), Toast.LENGTH_SHORT).show());

ok,非常简单,接下来我们来配置缓存,我们默认需求:缓存有效期为1分钟。

3.缓存配置

配置缓存接口

首先我们先配置Provider接口:

public interface UserCacheProviders {
  /**
   * LifeCache设置缓存过期时间. 如果没有设置@LifeCache , 数据将被永久缓存理除非你使用了 EvictProvider,EvictDynamicKey or EvictDynamicKeyGroup .
   * @param user
   * @param userName 驱逐与一个特定的键使用EvictDynamicKey相关的数据。比如分页,排序或筛选要求
   * @param evictDynamicKey  可以明确地清理指定的数据 DynamicKey.
   * @return
   */
  @LifeCache(duration = 1,timeUnit = TimeUnit.MINUTES)
  Observable<User> getUser(Observable<User> user, DynamicKey userName, EvictDynamicKey evictDynamicKey);
}

很多同学到这里就有点蒙蒙的,不知道这些参数都是用来干嘛的,其实简单介绍一下就清楚了:

@param user:这是个Observable类型的对象,简单来说,这就是你将要缓存的数据对象。
@param userName:DynamicKey类型,顾名思义,就是一个动态的key,我们以它作为tag,将数据存储到对应名字的File中
@param evictDynamicKey 可以明确地清理指定的数据 ,很简单,如果我们该参数传入为true,那么RxCache就会驱逐对应的缓存数据直接进行网络的新一次请求(即使缓存没有过期)。如果传入为false,说明不驱逐缓存数据,如果缓存数据没有过期,那么就不请求网络,直接读取缓存数据返回。
@return 可以看到,该接口方法中,返回值为Observable,泛型为user,这个Observable的对象user和参数中传进来的Observable的对象user有什么区别呢?
— 很简单,返回值Observable中的数据为经过缓存处理的数据。

配置缓存Provider

我们还需要配置的有:

1.缓存文件存储到哪里?

2.如何解析缓存数据?

public class CacheProviders {
  private static UserCacheProviders userCacheProviders;
  public synchronized static UserCacheProviders getUserCache() {
    if (userCacheProviders == null) {
      userCacheProviders = new RxCache.Builder()
          .persistence(BaseApplication.getApplication().getExternalCacheDir(), new GsonSpeaker())//缓存文件的配置、数据的解析配置
          .using(UserCacheProviders.class);//这些配置对应的缓存接口
    }
    return userCacheProviders;
  }
}

代码中设置缓存功能:

 private void requestHttp(String userName) {
     //网络请求数据
    Observable<User> user = new GitHubServiceManager()
        .getUser(userName);
    //缓存配置
    CacheProviders.getUserCache()
        .getUser(user, new DynamicKey(userName), new EvictDynamicKey(false))//用户名作为动态key生成不同文件存储数据,默认不清除缓存数据
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(user1 -> Toast.makeText(this, user1.toString(), Toast.LENGTH_SHORT).show());
}

配置好后,如果没有缓存或者缓存失效,则请求网络数据,缓存并展示数据。

如果有缓存数据且缓存未失效,则不加载网络数据,直接展示本地缓存数据。

以上这篇基于Android RxCache使用方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 浅谈Android轻量级的数据缓存框架RxCache
(0)

相关推荐

  • 浅谈Android轻量级的数据缓存框架RxCache

    请求网络数据是在安卓开发中使用最频繁的一个功能,网络请求的体验决定了用户对整个APP的感觉,因此合理地使用缓存对网络请求的数据进行处理极为重要.合理的进行缓存和网络请求,可以为APP带来更优秀的体验.图片的缓存有Picasso.Glide.Fresco等非常著名的框架,它们极为成熟并且使用广泛,程序员应该做的是使用轮子而非重复造轮子.但对于网络数据的缓存,大多都是自用自封装,每个人都需要进行繁琐的编码工作.RxCache就对网络缓存进行了封装,并采用RxJava模式,可以与其他RxJava的代码

  • 基于Android RxCache使用方法详解

    前言 我为什么使用这个库? 事实上Android开发中缓存功能的实现选择有很多种,File缓存,SP缓存,或者数据库缓存,当然还有一些简单的库/工具类,比如github上的这个: [ASimpleCache]:a simple cache for android and java 但是都不是很好用(虽然可能学习成本比较低,因为它使用起来相对简单),我可能需要很多的静态常量来作为key存储缓存数据value,并设置缓存的有效期,这可能需要很多Java代码去实现,并且过程繁琐. 如果您使用的网络请求

  • 基于Android FileProvider 属性配置详解及FileProvider多节点问题

    众所周知在android7.0,修改了对私有存储的限制,导致在获取资源的时候,不能通过Uri.fromFile来获取uri了我们需要适配7.0+的机型需要这样写: 1:代码适配 if (Build.VERSION.SDK_INT > 23) {// intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri contentUri = FileProvider.getUriForFile(context, SysInfo.packageN

  • Android HandlerThread使用方法详解

    Android HandlerThread使用方法详解 HandlerThread 继承自Thread,内部封装了Looper. 首先Handler和HandlerThread的主要区别是:Handler与Activity在同一个线程中,HandlerThread与Activity不在同一个线程,而是别外新的线程中(Handler中不能做耗时的操作). 用法: import android.app.Activity; import android.os.Bundle; import androi

  • 基于RestTemplate的使用方法(详解)

    1.postForObject :传入一个业务对象,返回是一个String 调用方: BaseUser baseUser=new BaseUser(); baseUser.setUserid(userid); baseUser.setPass(pass); String postForObject = restTemplate.postForObject(this.getURL()+"/user/login", baseUser, String.class); return postF

  • 基于python时间处理方法(详解)

    在处理数据和进行机器学习的时候,遇到了大量需要处理的时间序列.比如说:数据库读取的str和time的转化,还有time的差值计算.总结一下python的时间处理方面的内容. 一.字符串和时间序列的转化 time.strptime():字符串=>时间序列 time.strftime():时间序列=>字符串 import time start = "2017-01-01" end = "2017-8-12" startTime = time.strptime

  • Android canvas drawBitmap方法详解及实例

     Android canvas drawBitmap方法详解及实例 之前自己在自定义view,用到canvas.drawBitmap(Bitmap, SrcRect, DesRect, Paint)的时候,对其中的第2和3个参数的含义含糊不清.看源码函数也没理解,然后看了一些其他的博客加上自己的理解,整理如下.首先,我们看一张图片,今天就要绘制这张图片. 然后将图片用红色的线条分成4个部分,如下: 我们自定义一个View,代码如下: public class PoterDuffLoadingVi

  • Android View.onMeasure方法详解及实例

    Android View.onMeasure方法详解及实例 View在屏幕上显示出来要先经过measure(计算)和layout(布局). 1.什么时候调用onMeasure方法? 当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,"你想要用多大地方啊?",然后传入两个参数--widthMeasureSpec和heightMeasureSpec. 这两个参数指明控件可获得的空间以及关于这个空间描述的元数据. 更好的方法是你传递View的高度和宽度到setMeasuredDi

  • Android Notification 使用方法详解

    Android Notification 使用方法详解 用TaskStackBuilder来获取PendingIntent处理点击跳转到别的Activity,首先是用一般的PendingIntent来进行跳转. mBuilder = new NotificationCompat.Builder(this).setContent(view) .setSmallIcon(R.drawable.icon).setTicker("新资讯") .setWhen(System.currentTim

  • 基于GORM实现CreateOrUpdate方法详解

    目录 正文 GORM 写接口原理 Create Save Update & Updates FirstOrInit FirstOrCreate 方案一:FirstOrCreate + Assign 方案二:Upsert 总结 正文 CreateOrUpdate 是业务开发中很常见的场景,我们支持用户对某个业务实体进行创建/配置.希望实现的 repository 接口要达到以下两个要求: 如果此前不存在该实体,创建一个新的: 如果此前该实体已经存在,更新相关属性. 根据笔者的团队合作经验看,很多

  • Android IdleHandler使用方法详解

    正文 在Android中,Handler是一个使用的非常频繁的东西,输入事件机制和系统状态,都通过Handler来进行流转,而在Handler中,有一个很少被人提起但是却很有用的东西,那就是IdleHandler,它的源码如下. /** * Callback interface for discovering when a thread is going to block * waiting for more messages. */ public static interface IdleHa

随机推荐