我正在使用Delphi XE5为Android创建一个简单的游戏。我有一些资源,PNG和Jpegs,我想在我的程序加载所有资源时显示加载屏幕。
但我发现将TBitmap.LoadFromFile或TBitmap.LoadFromStream代码放入android线程中,导致App立即退出并返回Launcher,在调试模式下Delphi甚至没有捕获异常。 (该代码在Windows上运行良好,在Android上没有线程)
我不得不打开logcat看看发生了什么,我看到了“创建绘图上下文时出错”。
我的问题是有没有办法使用Delphi XE5为Android制作加载屏幕?因此,当图像加载到内存中时,会显示进度屏幕。
我创建测试项目只是为了隔离问题,这是结果。 LoadFromFile是线程1.日志建议线程实际运行,但之后引发了异常???
Logcat屏幕截图: 源代码:http://www.pockhero.com/wp-content/uploads/2013/10/threadtest1.7z
答案 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;