debug: glide sizing, memory cache clear
This commit is contained in:
parent
022ad0334e
commit
85a1b33e83
5 changed files with 75 additions and 7 deletions
|
@ -1,6 +1,8 @@
|
||||||
package deckers.thibault.aves.channel.calls
|
package deckers.thibault.aves.channel.calls
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
||||||
|
@ -21,7 +23,8 @@ class MediaFetchObjectHandler(private val context: Context) : MethodCallHandler
|
||||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||||
when (call.method) {
|
when (call.method) {
|
||||||
"getEntry" -> ioScope.launch { safe(call, result, ::getEntry) }
|
"getEntry" -> ioScope.launch { safe(call, result, ::getEntry) }
|
||||||
"clearSizedThumbnailDiskCache" -> ioScope.launch { safe(call, result, ::clearSizedThumbnailDiskCache) }
|
"clearImageDiskCache" -> ioScope.launch { safe(call, result, ::clearImageDiskCache) }
|
||||||
|
"clearImageMemoryCache" -> ioScope.launch { safe(call, result, ::clearImageMemoryCache) }
|
||||||
else -> result.notImplemented()
|
else -> result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,11 +50,18 @@ class MediaFetchObjectHandler(private val context: Context) : MethodCallHandler
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearSizedThumbnailDiskCache(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
private fun clearImageDiskCache(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
Glide.get(context).clearDiskCache()
|
Glide.get(context).clearDiskCache()
|
||||||
result.success(null)
|
result.success(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearImageMemoryCache(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
Glide.get(context).clearMemory()
|
||||||
|
}
|
||||||
|
result.success(null)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CHANNEL = "deckers.thibault/aves/media_fetch_object"
|
const val CHANNEL = "deckers.thibault/aves/media_fetch_object"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package deckers.thibault.aves.decoder
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.text.format.Formatter
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.GlideBuilder
|
import com.bumptech.glide.GlideBuilder
|
||||||
|
@ -10,9 +11,17 @@ import com.bumptech.glide.annotation.GlideModule
|
||||||
import com.bumptech.glide.load.DecodeFormat
|
import com.bumptech.glide.load.DecodeFormat
|
||||||
import com.bumptech.glide.load.ImageHeaderParser
|
import com.bumptech.glide.load.ImageHeaderParser
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPoolAdapter
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.LruArrayPool
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool
|
||||||
|
import com.bumptech.glide.load.engine.cache.DiskCache
|
||||||
|
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
||||||
|
import com.bumptech.glide.load.engine.cache.LruResourceCache
|
||||||
|
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator
|
||||||
import com.bumptech.glide.load.resource.bitmap.ExifInterfaceImageHeaderParser
|
import com.bumptech.glide.load.resource.bitmap.ExifInterfaceImageHeaderParser
|
||||||
import com.bumptech.glide.module.AppGlideModule
|
import com.bumptech.glide.module.AppGlideModule
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import deckers.thibault.aves.utils.LogUtils
|
||||||
import deckers.thibault.aves.utils.MimeTypes
|
import deckers.thibault.aves.utils.MimeTypes
|
||||||
import deckers.thibault.aves.utils.MimeTypes.isVideo
|
import deckers.thibault.aves.utils.MimeTypes.isVideo
|
||||||
import deckers.thibault.aves.utils.StorageUtils
|
import deckers.thibault.aves.utils.StorageUtils
|
||||||
|
@ -23,6 +32,30 @@ class AvesAppGlideModule : AppGlideModule() {
|
||||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||||
// hide noisy warning (e.g. for images that can't be decoded)
|
// hide noisy warning (e.g. for images that can't be decoded)
|
||||||
builder.setLogLevel(Log.ERROR)
|
builder.setLogLevel(Log.ERROR)
|
||||||
|
|
||||||
|
// sizing
|
||||||
|
val memorySizeCalculator = MemorySizeCalculator.Builder(context).build()
|
||||||
|
builder.setMemorySizeCalculator(memorySizeCalculator)
|
||||||
|
val size: Int = memorySizeCalculator.bitmapPoolSize
|
||||||
|
if (size > 0) {
|
||||||
|
builder.setBitmapPool(LruBitmapPool(size.toLong()))
|
||||||
|
} else {
|
||||||
|
builder.setBitmapPool(BitmapPoolAdapter())
|
||||||
|
}
|
||||||
|
builder.setArrayPool(LruArrayPool(memorySizeCalculator.arrayPoolSizeInBytes))
|
||||||
|
builder.setMemoryCache(LruResourceCache(memorySizeCalculator.memoryCacheSize.toLong()))
|
||||||
|
|
||||||
|
val diskCacheSize = DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE
|
||||||
|
val internalCacheDiskCacheFactory = InternalCacheDiskCacheFactory(context, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, diskCacheSize.toLong())
|
||||||
|
builder.setDiskCache(internalCacheDiskCacheFactory)
|
||||||
|
|
||||||
|
fun toMb(bytes: Int) = Formatter.formatFileSize(context, bytes.toLong())
|
||||||
|
Log.d(
|
||||||
|
LOG_TAG, "Glide disk cache size=${toMb(diskCacheSize)}" +
|
||||||
|
", memory cache size=${toMb(memorySizeCalculator.memoryCacheSize)}" +
|
||||||
|
", bitmap pool size=${toMb(memorySizeCalculator.bitmapPoolSize)}" +
|
||||||
|
", array pool size=${toMb(memorySizeCalculator.arrayPoolSizeInBytes)}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
|
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
|
||||||
|
@ -34,6 +67,8 @@ class AvesAppGlideModule : AppGlideModule() {
|
||||||
override fun isManifestParsingEnabled(): Boolean = false
|
override fun isManifestParsingEnabled(): Boolean = false
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val LOG_TAG = LogUtils.createTag<AvesAppGlideModule>()
|
||||||
|
|
||||||
// request a fresh image with the highest quality format
|
// request a fresh image with the highest quality format
|
||||||
val uncachedFullImageOptions = RequestOptions()
|
val uncachedFullImageOptions = RequestOptions()
|
||||||
.format(DecodeFormat.PREFER_ARGB_8888)
|
.format(DecodeFormat.PREFER_ARGB_8888)
|
||||||
|
|
|
@ -55,7 +55,9 @@ abstract class MediaFetchService {
|
||||||
int? priority,
|
int? priority,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> clearSizedThumbnailDiskCache();
|
Future<void> clearImageDiskCache();
|
||||||
|
|
||||||
|
Future<void> clearImageMemoryCache();
|
||||||
|
|
||||||
bool cancelRegion(Object taskKey);
|
bool cancelRegion(Object taskKey);
|
||||||
|
|
||||||
|
@ -255,9 +257,18 @@ class PlatformMediaFetchService implements MediaFetchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> clearSizedThumbnailDiskCache() async {
|
Future<void> clearImageDiskCache() async {
|
||||||
try {
|
try {
|
||||||
return _platformObject.invokeMethod('clearSizedThumbnailDiskCache');
|
return _platformObject.invokeMethod('clearImageDiskCache');
|
||||||
|
} on PlatformException catch (e, stack) {
|
||||||
|
await reportService.recordError(e, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> clearImageMemoryCache() async {
|
||||||
|
try {
|
||||||
|
return _platformObject.invokeMethod('clearImageMemoryCache');
|
||||||
} on PlatformException catch (e, stack) {
|
} on PlatformException catch (e, stack) {
|
||||||
await reportService.recordError(e, stack);
|
await reportService.recordError(e, stack);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ class _AboutDataUsageState extends State<AboutDataUsage> with FeedbackMixin {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await storageService.deleteTempDirectory();
|
await storageService.deleteTempDirectory();
|
||||||
await storageService.deleteExternalCache();
|
await storageService.deleteExternalCache();
|
||||||
await mediaFetchService.clearSizedThumbnailDiskCache();
|
await mediaFetchService.clearImageDiskCache();
|
||||||
imageCache.clear();
|
imageCache.clear();
|
||||||
_reload();
|
_reload();
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
|
@ -87,7 +87,19 @@ class _DebugCacheSectionState extends State<DebugCacheSection> with AutomaticKee
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: mediaFetchService.clearSizedThumbnailDiskCache,
|
onPressed: mediaFetchService.clearImageDiskCache,
|
||||||
|
child: const Text('Clear'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Expanded(
|
||||||
|
child: Text('Glide memory cache: ?'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: mediaFetchService.clearImageMemoryCache,
|
||||||
child: const Text('Clear'),
|
child: const Text('Clear'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue