1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-RxCache

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

RxCache

中文文档 (http://www.jianshu.com/p/b58ef6b0624b)

Для более реактивного подхода перейдите сюда (https://github.com/VictorAlbertos/ReactiveCache/tree/2.x).

Цель этой библиотеки проста: кэширование ваших моделей данных, как Picasso кэширует ваши изображения, без каких-либо усилий.

Каждое Android-приложение является клиентским приложением, а это значит, что нет смысла создавать и поддерживать базу данных только для кэширования данных.

Кроме того, тот факт, что у вас есть какая-то легендарная база данных для сохранения ваших данных, сам по себе не решает реальную проблему: возможность гибко и просто настроить ваши потребности в кэшировании.

Вдохновлённая API Retrofit, RxCache — это реактивная библиотека кэширования для Android и Java, которая превращает ваши потребности в кэшировании в интерфейс.

Когда вы предоставляете observable, single, maybe или flowable (это поддерживаемые типы Reactive), которые содержат данные, предоставленные дорогостоящей задачей (вероятно, HTTP-соединением), RxCache определяет, нужно ли подписаться на него или вместо этого получить ранее кэшированные данные. Это решение принимается на основе конфигурации провайдера.

Observable<List<Mock>> getMocks(Observable<List<Mock>> oMocks);

Настройка

Добавьте репозиторий JitPack в свой build.gradle (верхний уровень модуля):

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

И добавьте следующие зависимости в build.gradle модуля:

dependencies {
    compile "com.github.VictorAlbertos.RxCache:runtime:1.8.3-2.x"
    compile "io.reactivex.rxjava2:rxjava:2.1.6"
}

Поскольку RxCache внутренне использует Jolyglot для сериализации и десериализации объектов, вам необходимо добавить одну из следующих зависимостей в gradle.

dependencies {
    // Для использования Gson 
    compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.4'

    // Для использования Jackson
    compile 'com.github.VictorAlbertos.Jolyglot:jackson:0.0.4'

    // Для использования Moshi
    compile 'com.github.VictorAlbertos.Jolyglot:moshi:0.0.4'
}

Использование

Определите интерфейс с таким количеством методов, сколько необходимо для создания провайдеров кэширования:

interface Providers {

        @ProviderKey("mocks")
        Observable<List<Mock>> getMocks(Observable<List<Mock>> oMocks);

        @ProviderKey("mocks-5-minute-ttl")
        @LifeCache(duration = 5, timeUnit = TimeUnit.MINUTES)
        Observable<List<Mock>> getMocksWith5MinutesLifeTime(Observable<List<Mock>> oMocks);

        @ProviderKey("mocks-evict-provider")
        Observable<List<Mock>> getMocksEvictProvider(Observable<List<Mock>> oMocks, EvictProvider evictProvider);

        @ProviderKey("mocks-paginate")
        Observable<List<Mock>> getMocksPaginate(Observable<List<Mock>> oMocks, DynamicKey page);

        @ProviderKey("mocks-paginate-evict-per-page")
        Observable<List<Mock>> getMocksPaginateEvictingPerPage(Observable<List<Mock>> oMocks, DynamicKey page, EvictDynamicKey evictPage);

        @ProviderKey("mocks-paginate-evict-per-filter")
        Observable<List<Mock>> getMocksPaginateWithFiltersEvictingPerFilter(Observable<List<Mock>> oMocks, DynamicKeyGroup filterPage, EvictDynamicKey evictFilter);
}

RxCache предоставляет метод evictAll() для одновременного удаления всего кеша.

RxCache принимает в качестве аргумента набор классов, чтобы указать, как провайдеру необходимо обрабатывать кэшированные данные:

  • Реактивный тип — единственный объект, необходимый для создания провайдера. Этот Реактивный тип должен быть равен тому, который указан возвращаемым значением провайдера. EvictProvider позволяет явно удалить все данные, связанные с провайдером.

@ProviderKey — это аннотация для методов провайдера, которую настоятельно рекомендуется использовать. Пользователи Proguard должны применять эту аннотацию обязательно, иначе в качестве ключей кэша будут использоваться имена методов, и пользователи Proguard быстро столкнутся с проблемами. Подробные сведения см. в разделе Proguard. Аннотацию также полезно использовать, когда Proguard не применяется, так как она гарантирует, что вы сможете изменять имена методов без необходимости писать миграцию для старых файлов кэша.

EvictDynamicKey позволяет явно удалять данные конкретного DynamicKey.

EvictDynamicKeyGroup позволяет явно удалять данные конкретной DynamicKeyGroup.

DynamicKey — это оболочка вокруг объекта ключа для тех провайдеров, которым необходимо обрабатывать несколько записей, поэтому им нужно предоставить несколько ключей, например, конечные точки с требованиями к разбиению на страницы, упорядочиванию или фильтрации. Чтобы удалить данные, связанные с определённым ключом, используйте EvictDynamicKey.

DynamicKeyGroup — это оболочка вокруг ключа и группы для тех провайдеров, которые должны обрабатывать несколько сгруппированных записей, поэтому они должны предоставлять несколько ключей, организованных в группы, например, конечные точки с требованиями фильтрации И разбиения на страницы. Чтобы удалить данные, связанные с ключом определённой группы, используйте EvictDynamicKeyGroup.

Поддерживаемые аннотации:

  • @LifeCache устанавливает промежуток времени до того, как данные будут удалены. Если @LifeCache не указана, данные никогда не будут удалены, если только это не требуется явно с помощью EvictProvider, EvictDynamicKey или EvictDynamicKeyGroup.

  • @Actionable предлагает простой способ выполнения операций записи с использованием провайдеров. Подробнее здесь.

  • @SchemeMigration и @Migration предоставляют простой механизм для обработки миграций между выпусками. Подробнее здесь.

  • @Expirable определяет, будет ли этот провайдер исключён из процесса удаления или нет. Подробнее здесь.

  • @EncryptKey и @Encrypt обеспечивают простой способ шифрования/дешифрования данных на уровне сохраняемости. Подробнее. Класс RxProvidersActionable

RxProvidersActionable.mocks(RxProviders proxy);
RxProvidersActionable.mocksDynamicKey(RxProviders proxy, DynamicKey dynamicKey);
RxProvidersActionable.mocksDynamicKeyGroup(RxProviders proxy, DynamicKeyGroup dynamicKeyGroup);

Эти методы возвращают экземпляр класса Actions, поэтому теперь вы готовы использовать каждую операцию записи, доступную в классе Actions. Рекомендуется изучить класс ActionsTest, чтобы увидеть, какое действие лучше подходит для вашего случая. Если вы считаете, что какое-то действие было пропущено, не стесняйтесь открыть вопрос, чтобы запросить его.

Примеры действий:

ActionsProviders.mocks(rxProviders)
    .addFirst(new Mock())
    .addLast(new Mock())
    // Добавляем новый макет на 5 позицию
    .add((position, count) -> position == 5, new Mock())

    .evictFirst()
    // Удаляем первый элемент, если в кэше уже 300 записей
    .evictFirst(count -> count > 300)
    .evictLast()
    // Удаляем последний элемент, если в кэше уже 300 записей
    .evictLast(count -> count > 300)
    // Удаляем все неактивные элементы
    .evictIterable((position, count, mock) -> mock.isInactive())
    .evictAll()

    // Обновляем макет с идентификатором 5
    .update(mock -> mock.getId() == 5, mock -> {
        mock.setActive();
        return mock;
    })
    // Обновляем все неактивные макеты
    .updateIterable(mock -> mock.isInactive(), mock -> {
        mock.setActive();
        return mock;
    })
    .toObservable()
    .subscribe(processedMocks -> {})

Каждое из предыдущих действий будет выполнено только после того, как составная наблюдаемая получит подписку. Таким образом, элементы базового провайдера будут изменены без каких-либо усилий.

Миграции

RxCache предоставляет простой механизм для обработки миграций между выпусками.

Вам необходимо аннотировать интерфейс ваших провайдеров с помощью @SchemeMigration. Эта аннотация принимает массив аннотаций @Migration и, в свою очередь, аннотация @Migration принимает номер версии и массив классов, которые будут удалены из уровня персистентности.

@SchemeMigration({
            @Migration(version = 1, evictClasses = {Mock.class}),
            @Migration(version = 2, evictClasses = {Mock2.class}),
            @Migration(version = 3, evictClasses = {Mock3.class})
    })
interface Providers {}

Вы хотите аннотировать новую миграцию только тогда, когда новое поле было добавлено в модель класса, используемую RxCache.

Удаление классов или удаление полей классов будет обрабатываться автоматически RxCache, поэтому вам не нужно аннотировать новую миграцию, когда поле или весь класс был удалён.

Например:

Миграция была добавлена в какой-то момент. В конце концов, была добавлена вторая.

@SchemeMigration({
            @Migration(version = 1, evictClasses = {Mock.class}),
            @Migration(version = 2, evictClasses = {Mock2.class})
    })
interface Providers {}

Но теперь класс Mock был удалён из проекта, так что его класс больше нельзя ссылаться. Чтобы исправить это, просто удалите аннотацию миграции.

@SchemeMigration({
            @Migration(version = 2, evictClasses = {Mock2.class})
    })
interface Providers {}

Поскольку RxCache имеет внутренний процесс очистки памяти при необходимости, данные в конечном итоге будут выселены.

Шифрование

RxCache обеспечивает простой механизм шифрования данных.

Необходимо аннотировать интерфейс провайдеров с помощью @EncryptKey. Аннотация принимает строку в качестве ключа, необходимого для шифрования/дешифрования данных. Но вам нужно будет аннотировать записи вашего провайдера с помощью @Encrypt, чтобы сохранить данные в зашифрованном виде. Если @Encrypt не установлен, шифрование проводиться не будет.

Важно: если значение ключа, предоставленное на @EncryptKey, изменяется между компиляциями, то предыдущие сохранённые данные не смогут быть удалены или извлечены RxCache.

@EncryptKey("myStrongKey-1234")
interface Providers {
        @Encrypt
        Observable<List<Mock>> getMocksEncrypted(Observable<List<Mock>> oMocks);

        Observable<List<Mock>> getMocksNotEncrypted(Observable<List<Mock>> oMocks);
}

Настройка общего поведения

RxCache позволяет установить определённые параметры при создании экземпляра провайдера:

Настройка предела в мегабайтах для сохраняемых данных

По умолчанию RxCache устанавливает предел в 100 мегабайт, но вы можете изменить это значение, вызвав метод setMaxMBPersistenceCache при создании экземпляра провайдера.

new RxCache.Builder()
            .setMaxMBPersistenceCache(maxMgPersistenceCache)
            .persistence(cacheDir)
            .using(Providers.class);

Этот предел гарантирует, что диск не будет расти бесконечно, если у вас есть провайдеры с динамическими ключами, значения которых меняются динамически, например фильтры на основе местоположения GPS или динамические фильтры, предоставляемые вашим серверным решением.

Когда этот предел будет достигнут, RxCache не сможет сохранять новые данные на диске. Вот почему у RxCache есть автоматизированный процесс для удаления любой записи, когда порог памяти, назначенный уровню сохранения, близок к достижению, даже если срок жизни записи не был выполнен.

Но запись провайдера, аннотированная с помощью @Expirable и установившая значение false, будет исключена из процесса.

interface Providers {
    @Expirable(false)
    Observable<List<Mock>> getMocksNotExpirable(Observable<List<Mock>> oMocks);
}

Используйте просроченные данные, если загрузчик недоступен

По умолчанию RxCache выдаст RuntimeException, если кэшированные данные истекли, а данные, возвращённые наблюдаемым загрузчиком, равны нулю, предотвращая таким образом обслуживание данных, которые были помечены как удалённые.

Вы можете изменить это поведение, разрешив RxCache обслуживать удалённые данные, когда загрузчик вернул нулевые значения, установив значение true для useExpiredDataIfLoaderNotAvailable.

new RxCache.Builder()
            .useExpiredDataIfLoaderNotAvailable(true)
            .persistence(cacheDir)
            .using(Providers.class);

Рассмотрение Android

Чтобы создать экземпляр интерфейса, используемого в качестве поставщика RxCache, вам необходимо предоставить ссылку на файловую систему. На Android вы можете получить ссылку на файл, вызвав getFilesDir() из класса Android Application.

Также рекомендуется использовать этот класс Android Application для предоставления уникального экземпляра RxCache на протяжении всего жизненного цикла вашего приложения.

Для выполнения Observable в новом потоке и выдачи результатов через onNext в основном потоке пользовательского интерфейса следует использовать встроенные методы, предоставляемые RxAndroid.

Проверьте пример Android.

Retrofit

RxCache идеально подходит для Retrofit для создания репозитория автоматически управляемых кэшированных данных, указывающих на конечные точки. Вы можете проверить пример использования RxCache. Retrofit working together

Внутреннее устройство

RxCache получает данные из одного из трёх слоёв:

  • Слой памяти -> Работает на основе Apache ReferenceMap.
  • Персистентный слой -> RxCache использует внутри Jolyglot для сериализации и десериализации объектов.
  • Слой загрузчика (наблюдаемый, предоставляемый клиентской библиотекой).

Политика очень проста:

  • Если запрошенные данные находятся в памяти и не истек срок их действия, получить их из памяти.
  • Иначе, если запрошенные данные находятся в персистентном слое и не истек срок их действия, получить их оттуда.
  • В противном случае получить их из слоя загрузчика.

Proguard

Пользователи Proguard должны добавить две указанные строки в свой конфигурационный файл Proguard и использовать метод аннотации @ProviderKey для каждого метода, который используется в качестве провайдера. Без аннотации @ProviderKey вместо неё будет использоваться имя метода, что может привести к появлению провайдеров с одинаковыми именами, см. проблему #96 для получения подробной информации.

-dontwarn io.rx_cache2.internal.**
-keepclassmembers enum io.rx_cache2.Source { *; }
-keepclassmembernames class * { @io.rx_cache2.* <methods>; }

Автор

Виктор Альбертос

Версия RxCache для Swift:

RxCache: библиотека реактивного кэширования для Swift.

Библиотеки других авторов, использующие RxJava:

  • Mockery: библиотека для Android и Java для имитации и тестирования сетевых уровней со встроенной поддержкой Retrofit.
  • RxActivityResult: реактивная крошечная крутая мстительная библиотека, которая позволяет разорвать связь с реализацией OnActivityResult, поскольку она нарушает цепочку наблюдаемых.
  • RxFcm: расширение RxJava для Android Firebase Cloud Messaging (также известного как fcm).
  • RxSocialConnect: расширение OAuth RxJava для Android.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

RxCache — это реактивная библиотека кеширования для Android и Java, которая позволяет настроить кеширование через интерфейс. Развернуть Свернуть
Java
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/mirrors-RxCache.git
git@api.gitlife.ru:oschina-mirror/mirrors-RxCache.git
oschina-mirror
mirrors-RxCache
mirrors-RxCache
2.x