如何在Android中检测程序的终止?
当Windows程序终止时,它调用事件处理程序,如OnClose、OnDestroy和析构函数Destroy。当我想保存一些INI设置时,这些就是要保存的地方。我为所有这些事件编写了事件处理程序,但当我终止程序时,它们不会被处理 有人知道当Android程序终止时,我应该把要执行的代码放在哪里吗?我强烈怀疑这也适用于iOS 更新 Johan的答案也适用于Android,尽管现实比他的例子稍微复杂一些。好在它迫使我去做一些我从未听说过的事情。这是Embarcadero没有记录的定制,但FMX.Platform的代码非常有趣。定义了几个应用程序事件,其中三个似乎很有趣:aeEnteredBackground、aeWillBecomeInactive和aeWillTerminate。由于它们没有被记录在案,我推测它们做了他们名字所暗示的事情:发出信号,表示已经达到了背景状态,它将开始进入背景状态,并且它将(很快)终止。我改编了约翰的代码如下:如何在Android中检测程序的终止?,android,delphi,firemonkey,delphi-xe5,Android,Delphi,Firemonkey,Delphi Xe5,当Windows程序终止时,它调用事件处理程序,如OnClose、OnDestroy和析构函数Destroy。当我想保存一些INI设置时,这些就是要保存的地方。我为所有这些事件编写了事件处理程序,但当我终止程序时,它们不会被处理 有人知道当Android程序终止时,我应该把要执行的代码放在哪里吗?我强烈怀疑这也适用于iOS 更新 Johan的答案也适用于Android,尽管现实比他的例子稍微复杂一些。好在它迫使我去做一些我从未听说过的事情。这是Embarcadero没有记录的定制,但FMX.Pl
function TForm2.AppEvent (AAppEvent: TApplicationEvent; AContext: TObject) : Boolean;
begin
// do something here for when the app is sent to background
case AAppEvent of
(1) TApplicationEvent.aeEnteredBackground: ;// Something for OnDeactivated
// which does not exist
(2) TApplicationEvent.aeWillBecomeInactive: if Assigned (OnDeactivate)
then OnDeactivate (Self);
(3) TApplicationEvent.aeWillTerminate: if Assigned (OnClose)
then OnClose (Self);
end; // case
Result := True; // let iOS/Android know it worked...
end; // AppEvent //
当我标记事件1、2和3时,使用调试器的实验显示如下:将应用程序强制到后台会生成一系列事件:2、1、1、2。有一次我甚至得到了2,2,1,1,2,2。如果您的代码应该执行一次,那么请采取预防措施。但更好的是:aeWillTerminate做它所宣传的事情:当应用程序终止时,它发送一个信号。这样做的时间可能很短,我将测试它是否足以编写一个文件
我也在Win32中尝试了这段代码,但没有成功。上诉人没有被解雇。这迫使我立即在平板电脑上测试代码,这需要一些时间。遗憾。当用户离开您的活动(屏幕)时,系统调用onStop()停止活动。如果用户在活动停止时返回,系统将调用onRestart(),然后快速调用onStart()和onResume()。因此,建议编写代码并将其放在onStop()方法的主体中
在iOS中,应用程序很少关闭,而是进入后台模式。
这就是OnClose事件不触发的原因。我怀疑通过点击taskmanager中的“x”来终止应用程序实际上会强制终止该应用程序,但尚未对此进行测试。在任何情况下,这种用例都太少,无法进行编码。
在安卓系统中,情况基本相同 幸运的是,安德斯·奥尔森(Anders Ohlsson)就这一主题写了一篇内容丰富的博文,请参见此处:。
下面的文章基于此来捕捉实际的背景 诀窍是注册应用程序事件。见: 一些iOS示例代码手边没有Android,抱歉。
上述论坛的副本:
unit Unit1;
interface
uses
System.SysUtils, System.Classes, FMX.Forms, FMX.Platform;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
public
function AppEvent(AAppEvent: TApplicationEvent; AContext: TObject) : Boolean;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
function TForm1.AppEvent(AAppEvent: TApplicationEvent; AContext: TObject) : Boolean;
begin
if AAppEvent = TApplicationEvent.aeEnteredBackground then begin
// do something here for when the app is sent to background
end;
Result := True; // let iOS know it worked...
end;
procedure TForm1.FormCreate(Sender: TObject);
var
AppEventSvc: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(AppEventSvc)) then
AppEventSvc.SetApplicationEventHandler(AppEvent);
end;
end.
显然,这些事件应该在FMX.Platform.TApplication中触发合理的事件处理程序,但它们没有也许您应该扩展TApplication以添加这些事件处理程序,以便保持理智。
我建议提交一份质量保证报告 这里有一个关于扩展TApplication类的建议
type
TnotifyApplication = class(FMX.Platfrom.TApplication)
private
FOnStop: TnotifyEvent;
protected
procedure AppEvent(AAppEvent: TApplicationEvent; AContext: TObject): boolean;
procedure SetOnStop(value: TNotifyEvent);
procedure DoOnStop;
public
property OnStop: TNotifyEvent read FOnStop write SetOnStop;
end;
implementation
procedure TNotifyApplication.SetOnStop(value: TNotifyEvent);
begin
if Assigned(value) then begin
//register for the notification to call AppEvent
end else begin
//
end;
end;
procedure TNotifyApplication.DoOnStop;
begin
if Assigned(FOnStop) then FOnStop(self);
end;
procedure TNotifyApplication.AppEvent(AAppEvent: TApplicationEvent; AContext: TObject) : Boolean;
begin
//call the relevant do... Call depending in the exact event.
请不要在你对主题一无所知的地方发布答案。如果您不熟悉delphi和delphi xe5,您不应该回答带有这些标签的问题。感谢您详细的回答和+1!但我必须为Android测试它。我有更多的事情要报告时会回来的。我忘了说我也试过了,但没有成功。您的解决方案很好地替代了OnDeactivate。