Перейти к содержанию
Fire Monkey от А до Я
  • 0

Уничтожение приложения из него самого


Pax Beach

Вопрос

Мне необходимо, когда пользователь нажимает кнопку «Закрыть», уничтожить приложение. Если указать Action = caFree, приложение остается висеть в памяти, не уничтожается, методы Destroy в приложении и сервисе не срабатывают:

procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DM.LocationSensor.Active := false;
  Action := TCloseAction.caFree;
end;

Если уничтожить приложение в смартфоне через «Последние приложения», тогда приложение уничтожается, сервис приложения перезапускается, и продолжает работать — это мне и надо.

Помогите пожалуйста понять, как же правильно уничтожить приложение при закрытии основной формы?

Подойдут решения отправки Intent, куда нужно, или вызовы нативных методов.

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
В 02.07.2016 в 06:54, ZuBy сказал:

такие подойдут?

  • Application.Terminate;
  • SharedActivity.finish;

К сожалению, нет.

После вызова методов, приложение действительно закрывается, но продолжает висеть в списке последних приложений. А это в свою очередь не позволяет сервису данного приложения получать broadcast сообщения, пока я вручную не выброшу приложения из списка последних запущенных. Т.е. сервис после этих вызовов перезагружается (пересоздается и запускается), но не получает broadcast, который генерирует таймер внутри сервиса. Как только приложение руками убил — монитор выдает собщения:

Цитата

07-03 16:46:58.928: I/art(5270): Thread[2,tid=5275,WaitingInMainSignalCatcherLoop,Thread*=0xb8267238,peer=0x32c110a0,"Signal Catcher"]: reacting to signal 3

07-03 16:47:00.548: I/info(5270): ... Thread [-1358321360] ticked

07-03 16:47:00.550: I/art(5270): Wrote stack traces to '/data/anr/traces.txt'
 

Сервис снова перезапускается, и уже  событие, которое слушает broadcastreceiver, начинает принимать сообщения.

Вот что я уже испробовал вместе и по отдельности:

procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
  LJO: JObject;
begin
  // Action := TCloseAction.caMinimize;
  Action := TCloseAction.caFree;

  Application.Terminate;
  TAndroidHelper.Activity.finish;

   TJActivityManager.Wrap((LJO as ILocalObject).GetObjectID).killBackgroundProcesses
   (StringToJString('ru.MySoft.DMControl'));

   TJActivityManager.Wrap((LJO as ILocalObject).GetObjectID).killBackgroundProcesses
   (StringToJString('com.embarcadero.firemonkey.FMXNativeActivity'));
end;

 

Изменено пользователем Pax Beach
Ссылка на комментарий
  • 0
  • Модераторы

Ну такого вы не добьетесь. Если приложение висит в менеджере задач, не значит что оно работает в фоне. Там ведь карточки запущенных недавно приложении. Это можно отключить, но толку не будет.

А почему при закрытии не стартовать сервис?

Ссылка на комментарий
  • 0
3 часа назад, ZuBy сказал:

Ну такого вы не добьетесь. Если приложение висит в менеджере задач, не значит что оно работает в фоне. Там ведь карточки запущенных недавно приложении. Это можно отключить, но толку не будет.

А почему при закрытии не стартовать сервис?

Сервис стартует при старте приложения. При уничтожении приложения сервис перезапускается. В сервисе работает таймер, который раз в десять секунд отправляет приложению (и соответственно local service) Local Broadcast. При старте сервиса регистрируется Broadcast Receiver. Так вот после уничтожения приложения, но пока оно висит в списке последних, Handler перестает ловить события. Ждать можно сколько угодно, Android не чистит память самостоятельно, только когда я руками очищаю список последних приложений, как уже писал ранее.

Попробую ставить для вас пример для тестирования.

Ссылка на комментарий
  • 0
11 минуту назад, Andrey Efimov сказал:

т.е. как меняется поведение?

Появляется диалоговое окно с надписью "Handle null exception" кнопкой ОК. Приложение сразу вылетает. В общем-то оно уничтожается, как и при закрытии с Action := caFree.

На всякий случай я дал приложению android.permission.KILL_BACKGROUND_PROCESSES.

Изменено пользователем Pax Beach
Ссылка на комментарий
  • 0

Коллеги, в теме «Использование нативных LocalBroadcastManager и BroadcastReceiver» выложил пример работы с ресиверами без компонентов. На этом примере можно отловить суть проблемы.

А именно, сервис всегда должен получать определенные сообщения, посланные ему broadcast.

Но если запустить сервис, и нажать кнопку «Убить приложение», то сервис перезапустится, таймер в сервисе будет тикать, отправлять broadcast'ы, но ресивер не будет их принимать, пока руками не убить приложение в списке последних приложений. Тогда сервис снова перезапустится и будет нормально принимать сообщения.

Потратил несколько часов на создание этого тестового стенда. Буду рад любой помощи в решении проблемы.

Изменено пользователем Pax Beach
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...