Delphi XE8 TThread 在 Android 上冻结,但在 Windows 上运行

Delphi XE8 TThread Frozen on Android, but works on Windows

我将一个线程和一个同步过程用于一个简单的游戏循环。 在我的电脑上,Windows 7,它非常有效,但是当我在我的 android 设备上 运行 它并且在我点击播放和线程启动后屏幕变黑或有时变暗,有时它保持正常,但屏幕上所有可见的对象要么拉伸要么无法正确渲染;此时线程似乎被冻结了(主窗体的音乐仍在继续播放)。

这是线程本身:

procedure TTheThread.Loop;
begin
  MainForm.GameLoop;
end;

procedure TTheThread.Execute;
begin

    while NOT Terminated do 
    begin
      Application.ProcessMessages;

      TC:= TStopwatch.GetTimeStamp;

      //The Following repeats itself every second:    
      if TC>(TCTime+10000000) then
      begin
        TCTime:= TStopwatch.GetTimeStamp;
        TimeT:= TimeT+1; //Time in seconds

        //Increasing game playing speed:
        Gravity:= Gravity + 0.0075 * DEF;
        PJump:= PJump+IncJump
      end;

      //...just to have it on screen:
      With MainForm do
      Label1.Text:= IntToStr(TC);

      //This seems to make the loop run smooth and without lagging on my PC:    
      if TC>(TCLast) then
      begin
        Synchronize(Loop);
        TCLast:= TC;
      end;

    end;

end;

它是这样开始的:

  TCTime:= TStopwatch.GetTimeStamp;
  TCLast:= TCTime;

  GameThread:= TTheThread.Create(True);
  GameThread.FreeOnTerminate:= True;
  GameThread.Start;

您的线程中有一些不安全的代码,很容易导致死锁和死亡 UIs(以及其他问题)。 不要直接在线程中访问UI控件,您必须与主UI线程同步,例如与TThread.Synchronize()TThread.Queue(),例如:

TThread.Synchronize(nil,
  procedure
  begin
    MainForm.Label1.Text := IntToStr(TC);
  end
);

此外,也不要在线程中调用 Application.ProcessMessages()。它仅属于主 UI 线程。即便如此,如果您必须报告调用它,那么您很可能一开始就做错了。在正常情况下,您永远不必诉诸手动调用它。