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;
2、大家都要好好学习多线程、异步执行、同步对象及其管理:https://blog.csdn.net/pulledup/article/details/105617706
喜欢的话,就在下面点个赞、收藏就好了,方便看下次的分享: