Translations: 简体中文
In order to avoid repeated conversion of pictures and improve the loading speed of pictures Sketch, the result cache function will store the converted pictures on disk for a long time, and skip the conversion process next time you read them directly from disk.
The result caching function is managed by ResultCacheInterceptor, and DiskCache is managed by the storage management.
The default implementation of DiskCache is LruDiskCache:
- Default maximum capacity is 200 MB
- Clear old cache based on least used principle
In order to adapt to the differences between different platforms, the locations of cache directories are also different on different platforms.
The default result cache directories on Android are obtained in the following order:
/sdcard/Android/data/[APP_PACKAGE_NAME]/cache/sketch4/result/data/data/[APP_PACKAGE_NAME]/cache/sketch4/result
Tip
In order to be compatible with multiple processes, when using Sketch in a non-main process, the process name will be added after the cache directory name, such as "result:push"
The default results cache directory on iOS is:
val appCacheDirectory =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, true).first() as String
val resultCacheDir = "$appCacheDirectory/sketch4/result"The default results cache directory on jvm platforms is:
val appId = getJarPath(PlatformContext::class.java)
?.substringBefore("${File.separator}build${File.separator}") // Debug
?.substringBefore("${File.separator}app${File.separator}") // Release
?.md5()
?.let { "SketchImageLoader${File.separator}${it}" }
?: return null
// macOS
"/Users/[user]/Library/Caches/${appId}/sketch4/result"
// Windows
"C:\\Users\\[user]\\AppData\\Local\\${appId}\\Cache\\sketch4\\result"
// Linux
"/home/[user]/.cache/${appId}/sketch4/result"val appId = NSBundle.mainBundle.bundleIdentifier?.takeIf { it.isNotEmpty() }
?: NSBundle.mainBundle.bundlePath.takeIf { it.isNotEmpty() }
?.substringBefore("/build/")
?.md5()
?.let { "SketchImageLoader/${it}" }
?: return null
val resultCacheDir = "/Users/[user]/Library/Caches/${appId}/sketch4/result"The web platform does not yet support result caching
Warning
Since Sketch on JVM and macOS platforms defaults to using the program's runtime path to build the result cache directory, any change to the runtime path will cause the result cache to become invalid. Therefore, please configure a stable result cache directory when initializing Sketch.
When initializing Sketch, you can customize the implementation or various configurations of the result cache using the resultCache() or resultCacheOptions() methods of Sketch.Builder, as follows:
// Use the default LruDiskCache implementation and configure its parameters
Sketch.Builder(context).apply {
resultCacheOptions(
DiskCache.Options(
// Just choose one of directory and appCacheDirectory
directory = "/tmp/myapp/sketch/result".toPath(),
// or
appCacheDirectory = "/tmp/myapp".toPath(),
// or. AppDirs is available only on the JVM platform.
appCacheDirectory = AppDirs.getCacheDir("MyAppName").toOkioPath(),
// 100 MB
maxSize = 1024 * 1024 * 100,
// The app's management version number for the result cache.
// If you want to clear the old result cache, upgrade this version number.
appVersion = 1,
)
)
}.build()
// Use your own DiskCache implementation
class MyDiskCache : DiskCache {
// ...
}
Sketch.Builder(context).apply {
resultCache(MyDiskCache())
}.build()The result caching policy is used to control how to use the result caching. The default configuration is CachePolicy.ENABLED, which you can configure via the resultCachePolicy attribute of ImageRequest or ImageOptions:
ImageRequest(context, "https://example.com/image.jpg") {
// Disable
resultCachePolicy(CachePolicy.DISABLED)
// Read only
resultCachePolicy(CachePolicy.READ_ONLY)
// Write Only
resultCachePolicy(CachePolicy.WRITE_ONLY)
}By default, Sketch will automatically generate a result cache key based on the requested configuration, but you can also customize the result cache key with the following properties:
ImageRequest(context, "https://example.com/image.jpg") {
// Use custom result cache key
resultCacheKey("https://example.com/image.jpg?width=100&height=100")
// Modify the automatically generated result cache key
resultCacheKeyMapper(CacheKeyMapper { "${it}&width=100&height=100" })
}
ImageOptions {
// Use custom result cache key
resultCacheKey("https://example.com/image.jpg?width=100&height=100")
// Modify the automatically generated result cache key
resultCacheKeyMapper(CacheKeyMapper { "${it}&width=100&height=100" })
}You can also get the final result cache key through the following methods:
// The result cache key can be obtained through RequestContext in the customized Interceptor,
// Transformation, Fetcher, and Decoder components.
val requestContext: RequestContext = ...
requestContext.resultCacheKey
// Get the result cache key from ImageResult
val imageSuccess = sketch.execute(request) as ImageResult.Success
imageSuccess.resultCacheKeyYou can access the result cache by obtaining the result cache instance through
the sketch.resultCache property, but be careful to obtain the lock before accessing, so as to
avoid problems under multi-threading, as follows:
scope.launch {
val resultCache = sketch.resultCache
val resultCacheKey = requestContext.resultCacheKey
resultCache.withLock(resultCacheKey) {
// get
openSnapshot(resultCacheKey)?.use { snapshot ->
val dataPath: Path = snapshot.data
val metadataPath: Path = snapshot.metadata
val dataContent = fileSystem.source(dataPath).buffer().use {
it.readUtf8()
}
val metadataContent = fileSystem.source(metadataPath).buffer().use {
it.readUtf8()
}
}
// edit
val editor: DiskCache.Editor? = openEditor(resultCacheKey)
if (editor != null) {
try {
val dataPath: Path = editor.data
val metadataPath: Path = editor.metadata
fileSystem.sink(dataPath).buffer().use {
it.writeUtf8("data")
}
fileSystem.sink(metadataPath).buffer().use {
it.writeUtf8("metadata")
}
editor.commit()
} catch (e: Exception) {
editor.abort()
}
}
// remove
val cleared: Boolean = remove(resultCacheKey)
}
// Clear all
resultCache.clear()
}Caution
- openSnapshot and openEditor with the same key conflict with each other. For example, openSnapshot is not closed before openEditor is closed. Always returns null and vice versa
- So it must be executed inside withLock, otherwise unexpected events may occur.
For more available methods, please refer to DiskCache
The results cache is cleared under the following circumstances: