Android RxCache使用詳解

前言

我為什么使用這個庫?

事實上Android開發(fā)中緩存功能的實現(xiàn)選擇有很多種,F(xiàn)ile緩存,SP緩存,或者數(shù)據(jù)庫緩存,當(dāng)然還有一些簡單的庫/工具類,比如github上的這個:

【ASimpleCache】:a simple cache for android and java

但是都不是很好用(雖然可能學(xué)習(xí)成本比較低,因為它使用起來相對簡單),我可能需要很多的靜態(tài)常量來作為key存儲緩存數(shù)據(jù)value,并設(shè)置緩存的有效期,這可能需要很多Java代碼去實現(xiàn),并且過程繁瑣。

如果您使用的網(wǎng)絡(luò)請求庫是Retrofit+RxJava,那么我推薦使用RxCache,正如作者所說的:

RxCache is a reactive caching library for Android and Java which turns your caching needs into an interface.

RxCache是一個用于Android和Java的響應(yīng)式緩存庫,它可將您的緩存需求轉(zhuǎn)換為一個接口。

為什么寫這樣一篇文章

因為這個庫的官方文檔是!英!語!的!
這本身無可厚非,作為一個開發(fā)者,英語文檔的閱讀是不可避免的一項技能,但是筆者還是抽了一點時間將官方文檔做了漢化:

RxCache官方文檔中文翻譯

RxCache庫官方鏈接

文檔的翻譯比想象中的費力(每一個詞都試圖翻譯準(zhǔn)確),但數(shù)小時的努力之后,譯文的描述依然對于初次接觸該庫的開發(fā)者有著不小的學(xué)習(xí)難度,干脆自己寫一個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在內(nèi)部使用 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請求示例

我們假設(shè)這樣一個需求,通過傳入user名,返回User對應(yīng)信息,比如:

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數(shù)據(jù)類

@Data   //lombok插件的注解,自動生成get、set方法
public class User {

  public String login;

  public String name;
}

最后在我們的Activity中獲取數(shù)據(jù):

 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設(shè)置緩存過期時間. 如果沒有設(shè)置@LifeCache , 數(shù)據(jù)將被永久緩存理除非你使用了 EvictProvider,EvictDynamicKey or EvictDynamicKeyGroup .
     * @param user
     * @param userName 驅(qū)逐與一個特定的鍵使用EvictDynamicKey相關(guān)的數(shù)據(jù)。比如分頁,排序或篩選要求
     * @param evictDynamicKey   可以明確地清理指定的數(shù)據(jù) DynamicKey.
     * @return
     */
    @LifeCache(duration = 1,timeUnit = TimeUnit.MINUTES)
    Observable<User> getUser(Observable<User> user, DynamicKey userName, EvictDynamicKey evictDynamicKey);

}

很多同學(xué)到這里就有點蒙蒙的,不知道這些參數(shù)都是用來干嘛的,其實簡單介紹一下就清楚了:

  • @param user:這是個Observable類型的對象,簡單來說,這就是你將要緩存的數(shù)據(jù)對象。
  • @param userName:DynamicKey類型,顧名思義,就是一個動態(tài)的key,我們以它作為tag,將數(shù)據(jù)存儲到對應(yīng)名字的File中
  • @param evictDynamicKey 可以明確地清理指定的數(shù)據(jù) ,很簡單,如果我們該參數(shù)傳入為true,那么RxCache就會驅(qū)逐對應(yīng)的緩存數(shù)據(jù)直接進行網(wǎng)絡(luò)的新一次請求(即使緩存沒有過期)。如果傳入為false,說明不驅(qū)逐緩存數(shù)據(jù),如果緩存數(shù)據(jù)沒有過期,那么就不請求網(wǎng)絡(luò),直接讀取緩存數(shù)據(jù)返回。
  • @return 可以看到,該接口方法中,返回值為Observable,泛型為user,這個Observable的對象user和參數(shù)中傳進來的Observable的對象user有什么區(qū)別呢?
    --- 很簡單,返回值Observable中的數(shù)據(jù)為經(jīng)過緩存處理的數(shù)據(jù)。

配置緩存Provider

我們還需要配置的有:
1.緩存文件存儲到哪里?
2.如何解析緩存數(shù)據(jù)?

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())//緩存文件的配置、數(shù)據(jù)的解析配置
                    .using(UserCacheProviders.class);//這些配置對應(yīng)的緩存接口
        }
        return userCacheProviders;
    }
}

代碼中設(shè)置緩存功能:

 private void requestHttp(String userName) {
         //網(wǎng)絡(luò)請求數(shù)據(jù)
        Observable<User> user = new GitHubServiceManager()
                .getUser(userName);
        //緩存配置        
        CacheProviders.getUserCache()
                .getUser(user, new DynamicKey(userName), new EvictDynamicKey(false))//用戶名作為動態(tài)key生成不同文件存儲數(shù)據(jù),默認不清除緩存數(shù)據(jù)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(user1 -> Toast.makeText(this, user1.toString(), Toast.LENGTH_SHORT).show());
}

配置好后,如果沒有緩存或者緩存失效,則請求網(wǎng)絡(luò)數(shù)據(jù),緩存并展示數(shù)據(jù)。
如果有緩存數(shù)據(jù)且緩存未失效,則不加載網(wǎng)絡(luò)數(shù)據(jù),直接展示本地緩存數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容