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

Приостановить запущенный сервис


Rusland

Вопрос

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

  • 0
  • Модераторы

Приостановить (поставить на паузу) сервис нельзя, для остановки сервиса используйте метод stopSelf, пример тут: C:\Users\Public\Documents\Embarcadero\Studio\17.0\Samples\Object Pascal\Multi-Device Samples\Device Sensors and Services\AndroidNotificationServiceDemo\NotificationService\

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

Andrey Efimov, ваше сообщение отвечает на мой предыдущий вопрос! Спасибо... видимо я там что-то не так делаю, буду смотреть.

А вот по поводу приостановки... достаточно и полной остановки сервиса. В указанном примере сервис вызывается, видимо останавливается предыдущий и снова запускается.

Не понимаю, как из приложения послать сообщение/команду сервису чтобы он выполнил stopSelf и остановился?

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

Andrey Efimov, ваше сообщение отвечает на мой предыдущий вопрос! Спасибо... видимо я там что-то не так делаю, буду смотреть.

А вот по поводу приостановки... достаточно и полной остановки сервиса. В указанном примере сервис вызывается, видимо останавливается предыдущий и снова запускается.

Не понимаю, как из приложения послать сообщение/команду сервису чтобы он выполнил stopSelf и остановился?

все общение через Intent, смотрите внимательней демо-проекты.

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

все общение через Intent, смотрите внимательней демо-проекты.

ZuBy, я уже слышал это от вас раза три. Покажите пожалуйста как из приложения через Intent отправить сообщение в сервис (обратно я уже умею). Ответьте пожалуйста по существу в эту тему. Заранее благодарен 

Ссылка на комментарий
  • 1
procedure TForm1.Button2Click(Sender: TObject);
var
  LIntent: JIntent;
begin
  Log.D('Try to stop');
  LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString('com.embarcadero.services.MyService'));
  TAndroidHelper.Activity.stopService(LIntent);
end;

Так останавливать сервис из приложения подойдет?

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

Ошибся, никакого перезапуска не происходит, просто телефон слабенький и при переключении на Настройки-Приложения, программа успевала закрыться... из-за этого и видел перезапуск )

Ссылка на комментарий
  • 0
5 минут назад, Pax Beach сказал:

В событии сервиса OnStartCommand точно вращается стикер «не перезапускать сервис»?

В OnStartService у меня прописано только 

function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  ProcessWait(Intent, StartId); // запускаю поток
  Result := TJService.JavaClass.START_STICKY;
end;

Как тут Intent обработать?

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

В OnStartService у меня прописано только 


function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  ProcessWait(Intent, StartId); // запускаю поток
  Result := TJService.JavaClass.START_STICKY;
end;

Как тут Intent обработать?

А зачем его тут обрабатывать? В этот Intent только ClassName передается.

Я предлагал выше из приложения посылать в сервис StopService().

 

Ссылка на комментарий
  • 0
6 минут назад, Pax Beach сказал:

Я предлагал выше из приложения посылать в сервис StopService().

Видимо я не правильно задаю имя сервиса, потому что ничего не происходит )

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

Видимо я не правильно задаю имя сервиса, потому что ничего не происходит )

В манифесте приложения есть строчка типа

		<service android:exported="false" android:name="com.embarcadero.services.Project1" />

Это и есть имя сервиса.

Не могу проверить у себя пока — завис на том, как запустить сервис с TLocationSensor :(

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

В манифесте приложения есть строчка типа


		<service android:exported="false" android:name="com.embarcadero.services.Project1" />

Это и есть имя сервиса.

Ну значит я правильно указываю имя... странно что не реагирует... кстати и не стартует, если я пытаюсь вызывать сервис так:

procedure TFrmMain.StartService();
var
  LIntent: JIntent;
begin
  LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString('com.embarcadero.DService'));
  LIntent.setAction(StringToJString('StopIntent'));
  TAndroidHelper.Activity.startService(LIntent);
end;

А по поводу TLocationSensor в сервисе - какая у вас Delphi? В 10.1 вроде решена проблема. А в 10 версии тоже есть решение - я его тут выкладывал. Если нужно поищу.

Изменено пользователем Rusland
Ссылка на комментарий
  • 0
1 минуту назад, Rusland сказал:

А по поводу TLocationSensor в сервисе - какая у вас Delphi? В 10.1 вроде решена проблема. А в 10 версии тоже есть решение - я его тут выкладывал. Если нужно поищу.

Пробую Ваше решение на 10 Update 1, но оно не до конца работает, как я понял из темы (отписался в ветке).

А 10.1 Trial не полностью рабочий, снес пока Доктор не одумается или не купим лицензию.

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

Ну значит я правильно указываю имя... странно что не реагирует... кстати и не стартует, если я пытаюсь вызывать сервис так:


procedure TFrmMain.StartService();
var
  LIntent: JIntent;
begin
  LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString('com.embarcadero.DService'));
  LIntent.setAction(StringToJString('StopIntent'));
  TAndroidHelper.Activity.startService(LIntent);
end;

А по поводу TLocationSensor в сервисе - какая у вас Delphi? В 10.1 вроде решена проблема. А в 10 версии тоже есть решение - я его тут выкладывал. Если нужно поищу.

 

В названии сервиса нет ошибки? Метод запуска такой префикс класса использует «com.embarcadero.services.».
 

class procedure TLocalServiceConnection.StartService(const AServiceName: string);
var
  LIntent: JIntent;
  LService: string;
begin
  LIntent := TJIntent.Create;
  LService := AServiceName;
  if not LService.StartsWith('com.embarcadero.services.') then
    LService := 'com.embarcadero.services.' + LService;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString(LService));
  TAndroidHelper.Activity.startService(LIntent);
end;

 

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

Да, похоже проблема была именно в том что я указывал 'com.embarcadero.DService' (в манифесте так называется), а надо 'com.embarcadero.services.DService'.

Тьфу, я не в тот манифест смотрел и не на ту строчку ) Надо было искать в манифесте проекта )

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

Вылезла следующая проблема. Так как в сервисе у меня крутится поток, то чтобы остановить сервис, надо как-то мягко остановить поток.

В моем случае поток обращается к серверу через NetHTTPClient и ждет от него ответа (таймаут около минуты). Через минуту (или раньше, если сервер прислал сообщение) создается новый коннект и так бесконечно.

Если просто убить сервис, не останавливая поток, то через N-ое количество секунд происходит Segmentation fault неизвестно где и программа умирает.

Я пробовал в сервисе убивать поток таким образом:

// в основной программе
procedure TForm1.ButStopClick(Sender: TObject);
var
 LIntent: JIntent;
begin    
      LIntent := TJIntent.Create;
      LIntent.setClassName(
        TAndroidHelper.Context.getPackageName(),
        TAndroidHelper.StringToJString('com.embarcadero.services.DService'));
      LIntent.setAction(StringToJString('StopIntent'));
      TAndroidHelper.Activity.startService(LIntent);    
end;

....
// в сервисе
function TDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then begin
    JavaService.stopSelf;
    Result := TJService.JavaClass.START_NOT_STICKY;
    aWaitThread.Terminate;
    aWaitThread.WaitFor;
  end else begin
    ProcessWait(StartId);
    Result := TJService.JavaClass.START_STICKY;
  end;
end;

то основная программа не отвечает до тех пор, пока не выйдет этот таймаут и несколько раз вылезает табличка "Приложение не отвечает. Закрыть его?". Нажимаю Подождать и дальше (после завершения потока и сервиса) программа нормально. Естественно такой вариант не подходит, для пользователя все должно работать в любой момент и никаких зависаний быть не должно.

Сам поток в сервисе:

procedure TWaitThread.Execute;
var
  aResponser: TResponser;
begin
  try
    while not terminated do
    begin
      aResponser:=WaitAlarm;
    end;
    Log('DDDZ!!! Wait potok zavershilsya',[]);
  except on E:Exception do    
  end;
end;


function TWaitThread.WaitAlarm():TResponser;
var
  aResponser: TResponser;
begin
  try
    Sleep(60000); // заменил запрос к серверу на 60сек ожидания

    aResponser.Code:=200;
    aResponser.Response:='OK';
    if Assigned(FOnEndWait) then    
      FOnEndWait(Self, aResponser.Code, aResponser.Response); // говорим что wait-запрос закончен    
  finally
    Result:=aResponser;
  end;
end;

Как решить эту проблему?

 

PS. Проект прикрепляю DProj2.zip

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

В общем решил я проблему следующим образом - останавливаю поток, а не сервис (все равно кроме потока в сервисе ничего нет). Пока мне этого хватит )

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

В общем решил я проблему следующим образом - останавливаю поток, а не сервис (все равно кроме потока в сервисе ничего нет). Пока мне этого хватит )

Сервис занимает в памяти 10-15 Мб, процессор не ест пока стоит.

Останавливать его большой нужды для своих задач не вижу, кроме сервисной для сисадминов.

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

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

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

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

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

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

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

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

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

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