在Android下,PNG解码不是线程安全吗?

问题描述 投票:-2回答:1

使用Delphi 10.2.3:

我正在编写代码,一遍又一遍地重复解码多个线程中的同一组PNG图像。

一旦执行了线程,它就会使用FMX TBitmap组件的“LoadFromStream”方法来解码加载​​到TMemoryStream中的PNG文件(在线程内)。

在Windows下运行,没有问题。

在Android下运行我得到多个异常,它似乎只是在一些线程上随机触发: 1.例外“无法激活当前上下文” 2. EReadError“流错误”

如果我捕获异常并将流保存到文件,则PNG有效。

如果我同步解码“Bitmap.LoadFromStream(MemoryStream)”函数一切正常。

如果答案是PNG解码使用本机库不是线程安全的,那么在Android下是否有支持多线程PNG解码的替代解决方案?

示例代码:

procedure TImageDecodeThread.Execute;
var
  memStream  : TMemoryStream;
  dlBitmap   : TBitmap;
Begin
  memStream := TMemoryStream.Create;
  Try
    memStream.LoadFromFile('image'+ThreadName+'.png');
  Except
    on E : Exception do
    Begin
      DebugEntry('memstream:'+E.ClassName+', "'+E.Message+'", Size='+IntToStr(memStream.Size));
    End;
  End;
  memStream.Position := 0;

  dlBitmap := TBitmap.Create;
  Try
    dlBitmap.LoadFromStream(memStream);
  Except
    on E : Exception do
    Begin
      DebugEntry('decode'+E.ClassName+', "'+E.Message+'", Size='+IntToStr(memStream.Size));
      memStream.Position := 0;
      memStream.SaveToFile(ThreadName+'exception'.png');
    End
  End;
  memStream.Free;
  dlBitmap.Free;
End;

更新 我试图将TBitmap的LoadFromStream方法包装在一个关键部分中,它仍然会引发“无法激活当前上下文”异常。

android multithreading delphi png firemonkey
1个回答
-1
投票

PNG图像可以在android下的后台线程中工作,但也许不是Tbitmap;)Embarcedero说来自delphi tokyo Tbitmap可以在后台线程中工作,但实际上它是假的(或更好的说完全错误)!例如,当您创建Ttexture时,控件将注册一些消息进行侦听(如上下文丢失),但是消息事件只能从主线程发送和读取!所以他们是一个问题,通常会导致一些访问冲突或随机崩溃。我做了一些关于必须在纹理中纠正的注释,以使Tbitmap在https://github.com/Zeus64/alcinoe中的后台线程中完全起作用

还要注意,你说它在windows下工作,但它也是假的!它取决于您的视频驱动程序和directx的版本。在某些窗口上,它绝对不起作用,我还在embarcadero的质量门户网站上报告了许多这样的bug

作为结论:Tbitmap现在无法在后台线程中使用...

© www.soinside.com 2019 - 2024. All rights reserved.