2013-10-28 2 views
2

Когда программа Windows завершает работу, она вызывает обработчики событий, такие как OnClose, OnDestroy и деструктор Destroy. Когда я хочу сохранить некоторые настройки INI, это те места, которые должны быть. Я написал обработчики событий для всех этих событий, но они не обрабатываются, когда я завершаю программу.Как обнаружить завершение программы в Android?

Кто-нибудь знает, где я должен поместить код, который будет выполнен, когда программа Android завершится? Я сильно подозреваю, что это относится и к iOS.

Update

ответ Йохан работает на Android, а также, хотя реальность несколько сложнее, чем его примеры. Приятно было то, что он заставил меня попасть в TApplicationEvents, о чем я никогда не слышал. Как это не задокументировано Embarcadero, но код FMX.Platform достаточно интересен. Определено несколько ApplicationEvents, из которых три представляют интерес: aeEnteredBackground, aeWillBecomeInactive и aeWillTerminate. Поскольку они не документированы, я предполагал, что они сделали то, что предложили их имена: сигнализируя, что достигнуто фоновое состояние, что он начнет идти на задний план и что он скоро закончится. Я приспособил код Йохан следующим образом:

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 делает то, что он рекламирует: он посылает сигнал, когда приложение завершается. Время сделать это, вероятно, будет кратким, и я проверю, достаточно ли написать TIniFile.

Я тоже пробовал этот код в Win32, и это не работает. Приложение не запускается. Это заставляет меня немедленно проверять код на моем планшете, который занимает некоторое время. Жалость.

ответ

6

В IOS приложений редко близких, но войти в фоновый режим.
Именно поэтому событие OnClose не срабатывает. Я подозреваю, что убить приложение, нажав на «x» в taskmanager, на самом деле принудительно завершает работу приложения, но не проверил это. в любом случае этот прецедент слишком редкий для кода.
В Android все работает примерно так же.

К счастью, Андерс Ольссон написал очень информативное сообщение в блоге об этой теме, см. Здесь: http://blogs.embarcadero.com/ao/2013/05/01/39450.
Следующий пост основывается на этом, чтобы поймать фактическое фонирование https://forums.embarcadero.com/message.jspa?messageID=558241

Хитрость заключается в регистрации событий приложений. См.: http://docwiki.embarcadero.com/Libraries/XE5/en/FMX.Platform.TApplicationEvent

Некоторые примеры кода для 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, но они этого не делают. http://docwiki.embarcadero.com/Libraries/XE5/en/FMX.Forms.TApplication_Events
Возможно, вам следует расширить TApplication, чтобы добавить эти обработчики событий, чтобы можно было сохранить здравомыслие.
Я рекомендую подать отчет QA.

Предлагается расширенный класс 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. 
+0

Спасибо и +1 за ваш разработанный ответ! Я должен проверить его, хотя для Android. Я вернусь, когда мне еще нужно сообщить. Я забыл упомянуть, что я тоже пробовал OnDeactivate безрезультатно. Ваше решение является хорошей заменой для OnDeactivate. – Arnold

+0

Отлично работает! См. Мое обновление для результатов. – Arnold

-4

Когда пользователь покидает вашу деятельность (Экран), система вызывает onStop(), чтобы остановить действие. Если пользователь возвращается, когда действие остановлено, система вызывает onRestart(), за которым быстро следуют onStart() и onResume(). Поэтому рекомендуется писать код и помещать его в тело метода onStop().

http://developer.android.com/images/training/basics/basic-lifecycle-stopped.png

+0

Отредактировано, поэтому я могу отменить свой переход на нижний план. – Johan

+2

Пожалуйста, не публикуйте ответы, где вы ничего не знаете о теме. Если вы не знакомы с delphi и delphi xe5, вы не должны отвечать на вопросы, содержащие эти теги. –

Смежные вопросы