FMX.Platform.TApplicationEvent与delphi XE应用线程安全退出和手机重新线程安全进入前台

FMX.Platform.TApplicationEvent

与delphi XE应用线程安全退出和手机重新线程安全进入前台

一、TApplicationEvent响应过程和手机重新线程安全地进入到前台

function TfmxTestGYListview1.AppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
  Result := true;

  case AAppEvent of
    TApplicationEvent.WillTerminate:
      begin
        Memo1.Lines.Add('应用将要中断');
        {$IFDEF MSWINDOWS} //Windows下防止用户强行中断正在Rest响应数据的应用,否则内存泄漏::
        if IFutureCtL00001<>nil then
          if IFutureCtL00001.Status<>TTaskStatus.Completed then IFutureCtL00001.Wait(500);
        if IFutureDataDictionary<>nil then
          if IFutureDataDictionary.Status<>TTaskStatus.Completed then IFutureDataDictionary.Wait(800);
        if IFutureCtl03200<>nil then
          if IFutureCtl03200.Status<>TTaskStatus.Completed then IFutureCtl03200.Wait(800);
        if IFutureCtl03001<>nil then
          if IFutureCtl03001.Status<>TTaskStatus.Completed then IFutureCtl03001.Wait(8500);
        if IFutureIVTd01302<>nil then
          if IFutureIVTd01302.Status<>TTaskStatus.Completed then IFutureIVTd01302.Wait(8000);
        if FITask<>nil then
          if FITask.Status<>TTaskStatus.Completed then FITask.Wait( 2000 ); //INFINITE //}
        {$ENDIF}
      end;

    TApplicationEvent.EnteredBackground:
      begin
        TimerGlobal.Enabled := false;
        TimerGuangGao.Enabled := false;
        ///////////已进入后台千千万不与UI有任何交互,否则异常:////////////////////////////////////////////////////////
          //Memo1.Lines.Add('应用已进入后台');
          //Text_0201.Text:=TInterlocked(FRestSearchFrequency).ToString;
      end;
    TApplicationEvent.FinishedLaunching:
      begin
        Memo1.Lines.Add('应用完成系统载入:');
      end;
    TApplicationEvent.WillBecomeInactive:
      begin
        TimerGlobal.Enabled := false;
        TimerGuangGao.Enabled := false;
        Memo1.Lines.Add(
          'App切入后台再重新调入过程:'+sLineBreak
          +'1、应用将变为非活动状态:'+sLineBreak
          +string('').PadLeft(8,#32)+'此时就需提前关闭任何'+sLineBreak
          +string('').PadLeft(8,#32)+'与UI相关的线程与计时,'+sLineBreak
          +string('').PadLeft(8,#32)+'否则手机重新切到前台'+sLineBreak
          +string('').PadLeft(8,#32)+'会内部异常!');
        Memo1.Lines.Add(
          '*注意:已进入后台事件中:'
          +string('').PadLeft(8,#32)+'千万不能有与UI相关的'+sLineBreak
          +string('').PadLeft(8,#32)+'任何交互、线程与计时'+sLineBreak
          +string('').PadLeft(8,#32)+'否则手机重新切到前台'+sLineBreak
          +string('').PadLeft(8,#32)+'亦会内部异常!'+sLineBreak
          );
      end;
    TApplicationEvent.WillBecomeForeground:
      begin
        TimerGlobal.Enabled := true;
        Memo1.Lines.Add('2、应用将进入前台:');

        TimerGuangGao.Enabled := true;//}
      end;
    TApplicationEvent.BecameActive:
      begin
        TimerGlobal.Enabled := true;
        Memo1.Lines.Add('3、应用已变为活动状态:');

        TimerGuangGao.Enabled := true;
        TranslucentStatusAndNavBar(self, Rectangle_02);
        // 将状态栏与导航栏透明显示,顺便做一些每个窗口必须要做的处理
        Rectangle_02.Height := Rectangle_02.Height - 25; // 因为上面多加了25 }
      end;
    TApplicationEvent.TimeChange:
      begin
        //
        Memo1.Lines.Add('应用计时改变:');
      end;
    TApplicationEvent.LowMemory:
      begin
        //
        Memo1.Lines.Add('系统报应用高内存耗用:');
      end;
    TApplicationEvent.OpenURL:
      begin
        //
        Memo1.Lines.Add('App打开一个URL:');
      end;
  end;
end;

二、Windows下防止用户强行中断正在Rest响应数据的应用:

FormClose事件再次确认线程安全结束,否则内存泄漏:

procedure TfmxTestGYListview1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  TimerGlobal.Enabled := false;  //:关闭所有与UI相关地计时操作

  Action := TCloseAction.caMinimize;
  {$IFDEF MSWINDOWS }//Windows下再次防止用户强行中断正在Rest响应数据的应用,否则内存泄漏:
    if IFutureCtL00001<>nil then
      if IFutureCtL00001.Status<>TTaskStatus.Completed then IFutureCtL00001.Wait(500);
    if IFutureDataDictionary<>nil then
      if IFutureDataDictionary.Status<>TTaskStatus.Completed then IFutureDataDictionary.Wait(800);
    if IFutureCtl03200<>nil then
      if IFutureCtl03200.Status<>TTaskStatus.Completed then IFutureCtl03200.Wait(800);
    if IFutureCtl03001<>nil then
      if IFutureCtl03001.Status<>TTaskStatus.Completed then IFutureCtl03001.Wait(8500);
    if IFutureIVTd01302<>nil then
      if IFutureIVTd01302.Status<>TTaskStatus.Completed then IFutureIVTd01302.Wait(8000);
    if FITask<>nil then
      if FITask.Status<>TTaskStatus.Completed then FITask.Wait( 2000 ); //INFINITE //}
  {$ENDIF}
  if ListViewItem <> nil then ListViewItem := nil;
  Action := TCloseAction.caFree;
  fmxTestGYListview1 := nil;

end;

三、你别小看FormClose :主窗体FormClose的全过程

FormClose - >  FormCloseQuery - >  FormDeactivate

  //:窗体FormClose会先触发FormCloseQuery事件(可以在其中关闭与UI相关Rest线程计时、可在其中关闭本地的Query)
  FormClose中的Action := TCloseAction.caMinimize;//:最小化窗体,会触发FormDeactivate事件

FormDeactivate :指窗体处于非活动状态,一个处于非活动状态的窗体,它内部的UI的响应会暂时中断,什么意思呢,比如你正在从服务器Rest响应数据,那么这个时候后台的线程及其UI同步事件或过程都会暂时中断,直到重新恢复到“活动状态”:

(1)、在 Windows下:你把窗体最小化:会触发FormDeactivate事件; 你把焦点从该应用转移到别的应用窗体:也会触发FormDeactivate事件; 

(2)、在 Android或IOS下:你从App进入到手机的桌面:会触发FormDeactivate事件;你把查询焦点从该App转入其它App:会触发该App的FormDeactivate事件;

(3)、结论:FormDeactivate事件中谨慎使用ATimer.Enabled:=False;类似中断的OnTimer的语句,或谨慎使用中断查询的语句,否则OnTimer中的正常执行就被停止啦,你好问题不好找原因。应当将它们放入FormCloseQuery事件中去处理。

1、大家都要好好学习线程单元:System.Threading.pas;

扫描二维码关注公众号,回复: 11328915 查看本文章

2、大家都要好好学习多线程、异步执行、同步对象及其管理https://blog.csdn.net/pulledup/article/details/105617706

喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享:

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/106479590
今日推荐