Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
[FEAT] implement disk caching
Browse files Browse the repository at this point in the history
  • Loading branch information
kudanai committed Oct 12, 2020
1 parent f25a7b9 commit 32a2dcf
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 10 deletions.
2 changes: 2 additions & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ dependencies {

implementation "com.squareup.moshi:moshi:1.11.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.11.0"
implementation 'com.jakewharton:disklrucache:2.0.2'


implementation "com.squareup.okhttp3:okhttp:4.9.0"
implementation "ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0"
Expand Down
6 changes: 4 additions & 2 deletions library/src/main/java/io/dotlottie/loader/AbstractLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ abstract class AbstractLoader(protected val context: Context) {
* for this request only
*/
fun withConfig(config: DotLottieConfig) {
dlCallConfig = config
dlCallConfig = config.apply {
cacheManager?.initialize(context)
}
}


Expand All @@ -43,7 +45,7 @@ abstract class AbstractLoader(protected val context: Context) {
private val cacheManager: DotLottieCache
get() = dlCallConfig.cacheManager
?:DotLottieLoader.globalConfig.cacheManager
?:DefaultDotLottieCache
?:DefaultDotLottieCache.apply { initialize(context) }

private val cacheStrategy: DotLottieCacheStrategy
get() = dlCallConfig.cacheStrategy
Expand Down
7 changes: 7 additions & 0 deletions library/src/main/java/io/dotlottie/loader/DotLottieCache.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package io.dotlottie.loader

import android.content.Context
import io.dotlottie.loader.models.DotLottie

interface DotLottieCache {

/**
* if the cache requires any initialization on context, it should go here
* might get called more than once. Must handle state yourself
*/
fun initialize(context: Context)

/**
* fetch DotLottie from cache, with respect to the [DotLottieCacheStrategy]
* supplied. Return null to ignore cache
Expand Down
7 changes: 5 additions & 2 deletions library/src/main/java/io/dotlottie/loader/DotLottieLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import io.dotlottie.loader.models.DotLottieConfig
*/
class DotLottieLoader private constructor(private val context: Context) {


/**
* loads animation from assets
* might throw [java.io.IOException]
Expand Down Expand Up @@ -51,7 +50,11 @@ class DotLottieLoader private constructor(private val context: Context) {
* @param context context for this instantiation
*/
@JvmStatic
fun with(context: Context):DotLottieLoader = DotLottieLoader(context)
fun with(context: Context):DotLottieLoader {
// initialize cache-manager if there is one
globalConfig.cacheManager?.initialize(context)
return DotLottieLoader(context)
}

/**
* Exposed setter to alter the global configuration.
Expand Down
13 changes: 12 additions & 1 deletion library/src/main/java/io/dotlottie/loader/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.ContextWrapper
import androidx.lifecycle.LifecycleOwner
import java.io.IOException
import java.io.InputStream
import java.security.MessageDigest


internal fun String.lastSegmentName() = split("/").last()
Expand Down Expand Up @@ -43,4 +44,14 @@ fun Context.lifecycleOwner(): LifecycleOwner? {
} else {
null
}
}
}



val String.md5: String
get() {
val bytes = MessageDigest.getInstance("MD5").digest(this.toByteArray())
return bytes.joinToString("") {
"%02x".format(it)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
package io.dotlottie.loader.defaults

import android.content.Context
import androidx.collection.LruCache
import com.jakewharton.disklrucache.DiskLruCache
import io.dotlottie.loader.DotLottieCache
import io.dotlottie.loader.DotLottieCacheStrategy
import io.dotlottie.loader.md5
import io.dotlottie.loader.models.DotLottie
import java.io.File
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.lang.Exception

internal object DefaultDotLottieCache: DotLottieCache{

private val memoryCache = LruCache<String, DotLottie>(10)
private var diskCache: DiskLruCache? = null


override fun initialize(context: Context) {
if(diskCache==null || diskCache?.isClosed==true) {

try {
val dir = File(context.cacheDir, "dotLottieCache")

if (!dir.exists())
dir.mkdirs()

diskCache = DiskLruCache.open(
dir, 1, 1,
1024 * 1024 * 20 //20mb
)
} catch (e: Exception) {
e.printStackTrace()
}

}
}


override suspend fun fromCache(
Expand All @@ -17,11 +46,27 @@ internal object DefaultDotLottieCache: DotLottieCache{

// thoughts: two level cache to avoid hitting disk?
// or do we let diskLRUCache handle it?
val diskkey = cacheKey.md5

return when(cacheStrategy) {
DotLottieCacheStrategy.NONE -> null
DotLottieCacheStrategy.DISK, //todo: implement (just memory cache rn)
DotLottieCacheStrategy.MEMORY -> memoryCache.get(cacheKey)
DotLottieCacheStrategy.DISK -> {
//hit
memoryCache.get(cacheKey)?.let { return it }

//miss
diskCache?.get(diskkey)?.let {

(ObjectInputStream(it.getInputStream(0))
?.readObject() as DotLottie)
?.let {
memoryCache.put(cacheKey, it)
return it
}

}
}
}
}

Expand All @@ -30,10 +75,30 @@ internal object DefaultDotLottieCache: DotLottieCache{
cacheKey: String,
cacheStrategy: DotLottieCacheStrategy
) {

val diskkey = cacheKey.md5

when(cacheStrategy) {
DotLottieCacheStrategy.NONE -> {}
DotLottieCacheStrategy.DISK, // todo: implement (for now just memory cache)
DotLottieCacheStrategy.MEMORY -> memoryCache.put(cacheKey, dotLottie)
DotLottieCacheStrategy.DISK -> {
//layer 1
memoryCache.put(cacheKey, dotLottie)

// flush it
diskCache?.get(diskkey)?.let { diskCache?.remove(diskkey) }

//to disk
diskCache?.edit(diskkey)?.let { editor ->

val oos = ObjectOutputStream(editor.newOutputStream(0))
oos.writeObject(dotLottie)
oos.flush()
editor.commit()
}

}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.dotlottie.loader.models

import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import java.io.Serializable


internal val moshi by lazy {
Expand All @@ -26,7 +27,7 @@ data class Manifest(
val author: String,
val animations: List<ManifestAnimation>,
val custom: Map<String, Any>?
)
): Serializable

/**
* Animation spec as declared in the [Manifest].
Expand All @@ -38,7 +39,7 @@ data class ManifestAnimation(
val speed: Float = 1.0f,
val themeColor: String?,
val loop: Boolean = false
)
): Serializable

/**
* A DotLottie file
Expand All @@ -52,4 +53,4 @@ data class DotLottie(
//js
//resources
//previews
)
): Serializable

0 comments on commit 32a2dcf

Please sign in to comment.