XE5 Android TBitmap.LoadFromStream在一个线程内失败

时间:2013-10-14 16:28:50

标签: android multithreading delphi delphi-xe5

我正在使用Delphi XE5为Android创建一个简单的游戏。我有一些资源,PNG和Jpegs,我想在我的程序加载所有资源时显示加载屏幕。

但我发现将TBitmap.LoadFromFile或TBitmap.LoadFromStream代码放入android线程中,导致App立即退出并返回Launcher,在调试模式下Delphi甚至没有捕获异常。 (该代码在Windows上运行良好,在Android上没有线程)

我不得不打开logcat看看发生了什么,我看到了“创建绘图上下文时出错”。

我的问题是有没有办法使用Delphi XE5为Android制作加载屏幕?因此,当图像加载到内存中时,会显示进度屏幕。


我创建测试项目只是为了隔离问题,这是结果。 LoadFromFile是线程1.日志建议线程实际运行,但之后引发了异常???

Logcat屏幕截图:Logcat Result 源代码:http://www.pockhero.com/wp-content/uploads/2013/10/threadtest1.7z

2 个答案:

答案 0 :(得分:3)

这显然是一个应该在下次更新中修复的错误。要将修复程序应用于您的代码,请声明此过程:

uses
  Androidapi.NativeActivity,
  Posix.Pthread;


procedure MyEndThreadProc(ExitCode:Integer);
var
  PActivity: PANativeActivity;
begin
    PActivity := PANativeActivity(System.DelphiActivity);
    PActivity^.vm^.DetachCurrentThread(PActivity^.vm);
    pthread_exit(ExitCode);
end;

并将它从System.Classes分配给EndThreadProc:

procedure TForm1.FormCreate(Sender: TObject);
begin
  EndThreadProc := MyEndThreadProc;
end;

使用此修复程序,您可以使用

设置您的主题
FreeOnTerminate := true;

然后像这样的代码不会再崩溃应用程序:

TYourThread.Create(something, somethingelse).Start;

我必须赞扬Antonio Tortosa在Embarcadero论坛上发布此解决方案。

答案 1 :(得分:1)

经过大量的测试和同事的帮助,我和我的同事解决了这个问题。解决方案不是终止线程并保持线程运行。

我知道这有点奇怪。我试图关闭FreeOnTerminate,但它只控制线程对象,而不是实际线程。似乎syncrhonized调用不同步。我不知道实际使用或复制位图的时间和地点。 Possiblly在某处有另一个GUI线程,因为Delphi编译的Android lib代码无论如何都不在主线程中运行。

这是工作代码。

procedure TBitmapThread.Execute;
begin
  inherited;
  BeforeExecute;
  try
    fBitmap := TBitmap.CreateFromFile(TPath.Combine(TPath.GetDocumentsPath, 'koala.jpg'));
    // Sleep(2000);
    Synchronize(UpdateImage);
    // Keep the thread running
    while not Terminated do
    begin
      Sleep(100);
    end;
    fBitmap.Free;
  except
    on E:Exception do
    begin
      Log.d('TestThread Exception: ' + E.message);
    end;
  end;
  AfterExecute;
end;