PNG解码在Android下不是线程安全的吗? [英] Is PNG decoding not thread safe under android?

查看:139
本文介绍了PNG解码在Android下不是线程安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Delphi 10.2.3:

Using Delphi 10.2.3:

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

I am writing code that repeat-decodes the same set of PNG images in multiple threads over and over again.

一旦线程执行完毕,它将使用FMX TBitmap组件的"LoadFromStream"方法对加载到TMemoryStream(在线程内)的PNG文件进行解码.

Once the thread is executed, it uses an FMX TBitmap component's "LoadFromStream" method to decode a PNG file loaded into a TMemoryStream (within the thread).

在Windows下运行,没有问题.

Running under Windows, no issues.

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

Running under Android I get multiple exceptions and it appears to trigger randomly on just some of the threads:
1. Exception "Can not activate current context"
2. EReadError "stream error"

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

If I capture the exception and save the stream to a file, the PNG is valid.

如果我同步解码"Bitmap.LoadFromStream(MemoryStream)"功能,一切正常.

If I synchronize the decoding "Bitmap.LoadFromStream(MemoryStream)" function everything works.

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

If the answer is that PNG decoding is not thread safe using the native library, is there an alternative solution that does support multithreaded PNG decoding under Android?

示例代码:

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方法包装在关键部分中,但它仍然引发无法激活当前上下文"异常.

Update
I tried to wrap the TBitmap's LoadFromStream method inside a critical section and it still raises the "Can not activate current context" exception.

推荐答案

PNG图像可以在android下的后台线程中工作,但是也许Tbitmap不能工作;)Embarcedero说从delphi tokyo来看,Tbitmap可以在后台线程中工作,但实际上这是错误的(或者最好说完全是越野车)!例如,当您创建一个Ttexture时,该控件将注册一些消息以进行侦听(例如丢失上下文),但是可以发送消息事件,并且只能从主线程中读取消息!因此,这是一个问题,通常是由于随机访问导致访问冲突或崩溃.我在 https://github中对必须进行纹理校正的内容进行了一些注释,以使Tbitmap在后台线程中完全起作用. com/Zeus64/alcinoe

PNG images can work in background threads under android, BUT maybe Tbitmap not ;) Embarcedero say that from delphi tokyo Tbitmap can work in background thread, but in the reality it's false (or better say completely buggy)! For exemple when you create a Ttexture then the control will register some message to listen (like context lost), but message event can be sent and read ONLY from the main thread! so their is a problem, most often resulting at some access violation or crash at random time. I make some notes of what must be corrected in texture to make Tbitmap fully work in background thread in https://github.com/Zeus64/alcinoe

还请注意,您说它在Windows下运行,但这也是错误的!这取决于您的视频驱动程序和DirectX的版本.在某些Windows上,这绝对是行不通的,我还报告了embarcadero质量门户网站下的许多此类错误

Note also, you say it's work under windows, but it's also false! it's depend of your video driver and the version of directx. on some windows it's abslutely not work, i also report many bug like this under quality portal of embarcadero

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

As a conclusion: Tbitmap can't be use right now in background thread ...

这篇关于PNG解码在Android下不是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆