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

从Resources加载图片在Release模式下触发原生崩溃求助

MAUI类库嵌入图片Release模式崩溃问题

根据微软文档,加载嵌入图片的代码如下:

Assembly assembly = GetType().GetTypeInfo().Assembly;
using Stream stream = assembly.GetManifestResourceStream("Ringotan.KanjiControl.Resources.next_arrow.png");
_arrowImage = PlatformImage.FromStream(stream);

这段代码在Debug模式下运行完全正常,但在Release模式下会触发原生SIGSEGV崩溃,崩溃栈信息如下:

[libc.so] __memcpy_aarch64_simd

    SIGSEGV

backtrace:
  #00  pc 0x0000000000058158  /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy_aarch64_simd+280)
  #01  pc 0x000000000065bd04  /system/lib64/libhwui.so ((anonymous namespace)::FrontBufferedStream::read(void*, unsigned long) (.__uniq.259476571162685252206752541612201816602)+340)
  #02  pc 0x000000000065bd60  /system/lib64/libhwui.so ((anonymous namespace)::FrontBufferedStream::peek(void*, unsigned long) const (.__uniq.259476571162685252206752541612201816602)+48)
  #03  pc 0x00000000005b4168  /system/lib64/libhwui.so (SkCodec::MakeFromStream(std::__1::unique_ptr<SkStream, std::__1::default_delete<SkStream>>, SkSpan<SkCodecs::Decoder const>, SkCodec::Result*, SkPngChunkReader*, SkCodec::SelectionPolicy)+120)

这是原生崩溃,无法通过.NET异常捕获机制处理。

问题:是否有解决该崩溃的方法?如果没有,有没有更好的加载IImage的方式?

背景信息

  • 资源和代码均位于MAUI类库中,而非主MAUI应用项目;尝试从类库加载主项目的嵌入资源无法正常工作。
  • 资源已正确设置为「Build Action: Embedded Resource」。
  • 已禁用AOT和Trimming,问题依然存在。
  • Debug模式下代码正常运行,确认资源流名称正确。

解决方案与替代方案

1. 修复当前崩溃的方法

问题根源是using语句会在PlatformImage.FromStream调用后立即释放流,但部分平台的PlatformImage可能不会立即完成流读取,导致后续原生代码访问已释放的内存。可以尝试两种修复方式:

方式一:移除using声明,手动管理流生命周期
Assembly assembly = GetType().GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("Ringotan.KanjiControl.Resources.next_arrow.png");
_arrowImage = PlatformImage.FromStream(stream);
// 注意:部分平台会接管流的生命周期,无需手动关闭;若需释放,需确认图片加载完成后操作
方式二:将流复制到内存流中

通过内存流保留完整数据,避免原流被提前释放:

Assembly assembly = GetType().GetTypeInfo().Assembly;
using Stream originalStream = assembly.GetManifestResourceStream("Ringotan.KanjiControl.Resources.next_arrow.png");
using MemoryStream memoryStream = new MemoryStream();
originalStream.CopyTo(memoryStream);
memoryStream.Position = 0;
_arrowImage = PlatformImage.FromStream(memoryStream);

2. 更可靠的IImage加载方式

推荐使用MAUI内置的稳定API替代直接调用PlatformImage:

方式一:使用ImageSource.FromResource
var imageSource = ImageSource.FromResource("Ringotan.KanjiControl.Resources.next_arrow.png", typeof(YourClass).GetTypeInfo().Assembly);
using var stream = await imageSource.GetStreamAsync();
_arrowImage = PlatformImage.FromStream(stream);
方式二:使用BitmapImage.LoadAsync(.NET MAUI 8+)

这是官方推荐的跨平台API,内部已处理流生命周期和兼容性:

Assembly assembly = typeof(YourClass).GetTypeInfo().Assembly;
using Stream stream = assembly.GetManifestResourceStream("Ringotan.KanjiControl.Resources.next_arrow.png");
_arrowImage = await BitmapImage.LoadAsync(stream);

内容的提问来源于stack exchange,提问作者BlueRaja - Danny Pflughoeft

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:05:18