You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为.NET MAUI中的StreamImageSource禁用图片缓存?

.NET MAUI: 禁用StreamImageSource在Android上的Glide缓存

问题描述

使用UriImageSource时,可通过CachingEnabled = false轻松禁用图片缓存:

<Image x:Name="image"/>
var imageUri = "https://www.google.de/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png";
image.Source = new UriImageSource
{
    Uri = new Uri(imageUri),
    CachingEnabled = false
};

但使用StreamImageSource加载图片时,尽管该类无缓存控制属性,Android平台下MAUI底层依赖的Glide库仍会将图片缓存到FileSystem.CacheDirectory/image_manager_disk_cache目录。可通过以下代码确认缓存存在:

var imageCacheDir = Path.Combine(FileSystem.CacheDirectory, "image_manager_disk_cache");
if (Directory.Exists(imageCacheDir))
{
    foreach (var file in Directory.EnumerateFiles(imageCacheDir))
        Debug.WriteLine(file);
}

示例输出:

[0:] /data/user/0/com.companyname.imagecachetest/cache/image_manager_disk_cache/journal
[0:] /data/user/0/com.companyname.imagecachetest/cache/image_manager_disk_cache/5bcc99fe6930c85add40cfc486ae9a5a0451c08d71c6d3cd679ea26ec0293b9b.0

解决方案

方案1:全局禁用Glide缓存

通过自定义Glide配置,在Android项目中全局禁用磁盘和内存缓存:

  1. 在Android项目中创建CustomGlideModule类:
using Android.App;
using Android.Content;
using Android.Glide;
using Android.Glide.Modules;
using Android.Glide.Request;

namespace YourAppNamespace.Droid
{
    [Application]
    public class CustomGlideModule : AppGlideModule
    {
        public override void ApplyOptions(Context context, GlideBuilder builder)
        {
            // 禁用磁盘缓存(设置缓存大小为0)
            builder.SetDiskCache(new InternalCacheDiskCacheFactory(context, 0));
            // 禁用内存缓存
            builder.SetMemoryCache(new LruResourceCache(0));
        }
    }
}

方案2:针对StreamImageSource单独禁用缓存

如果仅需对StreamImageSource禁用缓存,保留其他图片的缓存逻辑,可自定义ImageHandler替换默认实现:

  1. 在Android项目中创建自定义Handler:
using Android.Widget;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
using Android.Graphics.Drawables;

namespace YourAppNamespace.Droid
{
    public class NoCacheImageHandler : ImageHandler
    {
        protected override ImageView CreatePlatformView() => new ImageView(Context);

        protected override void ConnectHandler(ImageView platformView)
        {
            base.ConnectHandler(platformView);
            UpdateImageSource(platformView);
        }

        private void UpdateImageSource(ImageView platformView)
        {
            if (VirtualView.Source is StreamImageSource streamSource)
            {
                // 直接加载流,绕过Glide缓存机制
                _ = streamSource.Stream.Invoke(default).ContinueWith(task =>
                {
                    if (!task.IsFaulted && task.Result != null)
                    {
                        Context.RunOnUiThread(() =>
                        {
                            using var stream = task.Result;
                            var drawable = Drawable.CreateFromStream(stream, null);
                            platformView.SetImageDrawable(drawable);
                        });
                    }
                });
            }
            else
            {
                // 其他ImageSource类型沿用默认加载逻辑
                base.UpdateValue(nameof(IImage.Source));
            }
        }

        protected override void DisconnectHandler(ImageView platformView)
        {
            platformView.SetImageDrawable(null);
            base.DisconnectHandler(platformView);
        }
    }
}
  1. 在MAUI项目的MauiProgram.cs中注册该Handler:
using Microsoft.Maui.Hosting;
using YourAppNamespace.Droid;

namespace YourAppNamespace
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureMauiHandlers(handlers =>
                {
#if ANDROID
                    handlers.AddHandler<Microsoft.Maui.Controls.Image, NoCacheImageHandler>();
#endif
                });

            return builder.Build();
        }
    }
}

方案3:手动清理缓存(临时方案)

若仅需在特定场景清理缓存,可直接删除Glide缓存目录下的文件:

var imageCacheDir = Path.Combine(FileSystem.CacheDirectory, "image_manager_disk_cache");
if (Directory.Exists(imageCacheDir))
{
    foreach (var file in Directory.EnumerateFiles(imageCacheDir))
    {
        try { File.Delete(file); }
        catch { /* 忽略删除失败的文件 */ }
    }
}

注意:此方法会清除所有Glide缓存,适合一次性使用场景。


内容的提问来源于stack exchange,提问作者Clemens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:24:52