使用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方法包装在关键部分中,但它仍然引发“无法激活当前上下文”异常。
答案 0 :(得分:-1)
PNG图像可以在Android下的后台线程中工作,但Tbitmap可能不是;)Embarcedero说从delphi tokyo Tbitmap可以在后台线程中工作,但实际上这是错误的(或者最好说完全是越野车)!例如,当您创建Ttexture时,控件将注册一些消息以进行侦听(例如丢失上下文),但是可以发送消息事件,并且只能从主线程中读取消息!因此它们是一个问题,通常是由于随机访问导致访问冲突或崩溃。我记下了一些必须纠正的纹理,以使Tbitmap在https://github.com/Zeus64/alcinoe
中的后台线程中完全起作用还请注意,您说它在Windows下运行,但这也是错误的!这取决于您的视频驱动程序和DirectX的版本。在某些Windows上,这绝对是行不通的,我还报告了embarcadero质量门户网站下的许多此类错误
作为结论:Tbitmap现在不能在后台线程中使用...