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

Выполнение регулярных операций в сервисе - статистика


Евгений Корепов

Вопрос

Провел небольшое исследование поведения таймера Posix в сервисе. Результаты не очень. Таймер ведет себя так же как и в приложении, главное отличие - не умирает окончательно, но рассчитывать на него не стоит.

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

2017-02-24 23:22:51 - телефон ушел в сон. Таймер начал работать эпизодически, с провалами до получаса.

2017-02-25 07:24:58 - я проснулся и разблокировал телефон. Таймер опять нормально заработал.

В следующей серии попробую протестировать сервис с AlarmManager, что то у меня подозрения что результаты будут не лучше.

2017-02-25 07:27:58	Posix-таймер в сервисе. Запрос раз в 60 сек. № 108
2017-02-25 07:26:58	Posix-таймер в сервисе. Запрос раз в 60 сек. № 107
2017-02-25 07:25:58	Posix-таймер в сервисе. Запрос раз в 60 сек. № 106
2017-02-25 07:24:58	Posix-таймер в сервисе. Запрос раз в 60 сек. № 105
2017-02-25 07:21:05	Posix-таймер в сервисе. Запрос раз в 60 сек. № 104
2017-02-25 07:14:00	Posix-таймер в сервисе. Запрос раз в 60 сек. № 103
2017-02-25 07:01:59	Posix-таймер в сервисе. Запрос раз в 60 сек. № 102
2017-02-25 06:46:33	Posix-таймер в сервисе. Запрос раз в 60 сек. № 101
2017-02-25 06:24:50	Posix-таймер в сервисе. Запрос раз в 60 сек. № 100
2017-02-25 06:13:58	Posix-таймер в сервисе. Запрос раз в 60 сек. № 99
2017-02-25 05:51:32	Posix-таймер в сервисе. Запрос раз в 60 сек. № 98
2017-02-25 05:30:07	Posix-таймер в сервисе. Запрос раз в 60 сек. № 97
2017-02-25 05:16:28	Posix-таймер в сервисе. Запрос раз в 60 сек. № 96
2017-02-25 05:07:28	Posix-таймер в сервисе. Запрос раз в 60 сек. № 95
2017-02-25 05:00:41	Posix-таймер в сервисе. Запрос раз в 60 сек. № 94
2017-02-25 04:41:01	Posix-таймер в сервисе. Запрос раз в 60 сек. № 93
2017-02-25 04:21:19	Posix-таймер в сервисе. Запрос раз в 60 сек. № 92
2017-02-25 04:00:40	Posix-таймер в сервисе. Запрос раз в 60 сек. № 91
2017-02-25 03:41:33	Posix-таймер в сервисе. Запрос раз в 60 сек. № 90
2017-02-25 03:16:59	Posix-таймер в сервисе. Запрос раз в 60 сек. № 89
2017-02-25 03:02:01	Posix-таймер в сервисе. Запрос раз в 60 сек. № 88
2017-02-25 02:44:54	Posix-таймер в сервисе. Запрос раз в 60 сек. № 87
2017-02-25 02:23:49	Posix-таймер в сервисе. Запрос раз в 60 сек. № 86
2017-02-25 02:10:28	Posix-таймер в сервисе. Запрос раз в 60 сек. № 85
2017-02-25 01:52:11	Posix-таймер в сервисе. Запрос раз в 60 сек. № 84
2017-02-25 01:32:57	Posix-таймер в сервисе. Запрос раз в 60 сек. № 83
2017-02-25 01:28:26	Posix-таймер в сервисе. Запрос раз в 60 сек. № 82
2017-02-25 01:27:26	Posix-таймер в сервисе. Запрос раз в 60 сек. № 81
2017-02-25 01:26:26	Posix-таймер в сервисе. Запрос раз в 60 сек. № 80
2017-02-25 01:25:27	Posix-таймер в сервисе. Запрос раз в 60 сек. № 79
2017-02-25 01:10:59	Posix-таймер в сервисе. Запрос раз в 60 сек. № 78
2017-02-25 01:00:27	Posix-таймер в сервисе. Запрос раз в 60 сек. № 77
2017-02-25 00:38:59	Posix-таймер в сервисе. Запрос раз в 60 сек. № 76
2017-02-25 00:19:22	Posix-таймер в сервисе. Запрос раз в 60 сек. № 75
2017-02-25 00:01:27	Posix-таймер в сервисе. Запрос раз в 60 сек. № 74
2017-02-24 23:51:15	Posix-таймер в сервисе. Запрос раз в 60 сек. № 73
2017-02-24 23:30:37	Posix-таймер в сервисе. Запрос раз в 60 сек. № 72
2017-02-24 23:22:51	Posix-таймер в сервисе. Запрос раз в 60 сек. № 71
2017-02-24 23:21:51	Posix-таймер в сервисе. Запрос раз в 60 сек. № 70
2017-02-24 23:20:51	Posix-таймер в сервисе. Запрос раз в 60 сек. № 69
2017-02-24 23:19:51	Posix-таймер в сервисе. Запрос раз в 60 сек. № 68
2017-02-24 23:18:51	Posix-таймер в сервисе. Запрос раз в 60 сек. № 67
2017-02-24 23:17:52	Posix-таймер в сервисе. Запрос раз в 60 сек. № 66
2017-02-24 23:16:52	Posix-таймер в сервисе. Запрос раз в 60 сек. № 65

 

Изменено пользователем Евгений Корепов
Ссылка на комментарий

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

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

Скорей всего режим Doze Mode (Android 6.0+) не будет нормально давать работать, что в принципе и правильно

Ссылка на комментарий
  • 0
4 часа назад, Равиль Зарипов (ZuBy) сказал:

Скорей всего режим Doze Mode (Android 6.0+) не будет нормально давать работать, что в принципе и правильно

Тестировал на 5 андроиде.

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

Попробовал AlarmManager. Интервал 30 секунд.

Запускал сервис следующим образом:

procedure TFormMain.InitServiceAlarmManager;
var Intent: JIntent;
    PendingIntent: JPendingIntent;
    ATimerInterval : Integer;
begin
  ATimerInterval:=30;
  Intent := TJIntent.Create;
  Intent.setClassName(TAndroidHelper.Context, StringToJString('com.embarcadero.services.ServiceTest090Service'));
  PendingIntent := TJPendingIntent.JavaClass.getService(TAndroidHelper.Context, 1, Intent, 0);
  TAndroidHelper.AlarmManager.&setRepeating(TJAlarmManager.JavaClass.RTC_WAKEUP, getTimeAfterInSecs(ATimerInterval),
    ATimerInterval * 1000, PendingIntent);
end;

procedure TFormMain.FormCreate(Sender: TObject);
begin
  InitServiceAlarmManager;
//  FService:=TLocalServiceConnection.Create;
//  FService.StartService('ServiceTest090Service');
end;

function TFormMain.getTimeAfterInSecs(Seconds: Integer): Int64;
Var Calendar: JCalendar;
begin
  Calendar := TJCalendar.JavaClass.getInstance;
  Calendar.add(TJCalendar.JavaClass.SECOND, Seconds);
  Result := Calendar.getTimeInMillis;
end;

end.

Результат - та же хрень, вид сбоку:

2017-02-25 21:35:40	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:35:40	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:34:40	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:34:40	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:33:38	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:33:10	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:32:45	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:32:10	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:32:10	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:31:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:30:59	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
А тут я заблокировал телефон кнопкой и началось....
2017-02-25 21:30:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:29:36	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:29:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:28:36	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:28:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:27:36	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:27:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:26:36	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:26:07	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:25:36	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-25 21:25:06	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.

Оставлю на ночь, посмотрим что будет....

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

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

А вообще, я как-то заморачивался с похожей проблемой и вроде нашёл то ли флаг, то ли ещё что-то. Смысл был в том, чтобы будить устройство, но не включать дисплей.

Кстати, HTC точно надо принудительно будить, у них ОСь так устроена.

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

Результаты ночного теста получились удивительными! AlarmManager отработал на ура (И кстати на HTC). Результаты можно посмотреть здесь http://kayfolom.ru/index.php?cmd=read&api_key=androidservicetest089

Правда есть некие странности, но думаю это проблемы моего кода. 

Некоторые вызовы удваиваются и утраиваются вот так (должно быть раз в 60 сек): 

2017-02-26 01:28:43	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:27:43	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:26:43	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:26:11	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:25:11	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:24:11	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:24:11	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.
2017-02-26 01:24:11	195.22.104.13	AlarmManager в сервисе. Запрос раз в 0 сек.

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

Вот код сервиса:

function TDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  SendRequest;
  Result:=TJService.JavaClass.START_NOT_STICKY;
end;

procedure TDM.SendRequest;
Var Query : String;
    AMessage,AAPIKey : String;
begin
  AAPIKey:='androidservicetest089';
  AMessage:='AlarmManager в сервисе. Запрос раз в '+TimerInterval.ToString+' сек.';
  Query:='http://kayfolom.ru/index.php?cmd=write&api_key='+AAPIKey+'&message='+AMessage;
  FHTTPThread:=THTTPThread.Create(Query);
end;

Поток с   FreeOnTerminate:=True;

Вроде все нормально...

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

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

А вообще, я как-то заморачивался с похожей проблемой и вроде нашёл то ли флаг, то ли ещё что-то. Смысл был в том, чтобы будить устройство, но не включать дисплей.

Кстати, HTC точно надо принудительно будить, у них ОСь так устроена.

Я знаю как на этом форуме относятся к идеям заставить мобильное устройство что то мониторить круглые сутки - начинаются крики "Ересь! Это не возможно! Сжечь его на костре пока не поздно!" :-)

Но я считаю что в нашей области нужно ограничиваться только фантазией и не слушать запретителей и ограничителей.

Задача у меня следующая - есть несколько моих приложений мониторинга майнинга криптовалюты, нужно добавить туда возможность мониторить круглые сутки воркеров (на человеческом языке это комп с 5-6 видеокартами, так называемая "ферма", или аппаратный модуль майнинга). В ответ на "сожрет батарею нафик" - одна ферма может зарабатывать от нескольких сотен рублей, до нескольких тысяч долларов в сутки, и понятно что человеку имеющему шанс потерять много денег, лучше узнать вовремя о зависании фермы в 23:15, чем обнаружить это утром и потерять деньги. С ужасной трагедией в виде севшего на 20% больше чем обычно аккумулятора телефона он, после многолетнего посещения психотерапевтов, думаю смирится.

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

При мониторинге с телефонов (а теперь ясно что это работает и достаточно стабильно) каждый сможет включать эту функцию по желанию, и мониторить только нужные (проблемные) фермы. 

 

По поводу флага - метод RTC_WAKEUP вроде так и работает, будит телефон для выполнение задачи, но экран не включается. По крайней мере в варианте getService. У меня экран телефона всю ночь был выключен, запросы шли стабильно.

Ссылка на комментарий
  • 0
  • Модераторы
1 час назад, Евгений Корепов сказал:

Я знаю как на этом форуме относятся к идеям заставить мобильное устройство что то мониторить круглые сутки - начинаются крики "Ересь! Это не возможно! Сжечь его на костре пока не поздно!" :-)

:D Ну, не знаю как остальным, мне просто была интересна сама задача. И задачка интересная :)

1 час назад, Евгений Корепов сказал:

При мониторинге с телефонов (а теперь ясно что это работает и достаточно стабильно) каждый сможет включать эту функцию по желанию, и мониторить только нужные (проблемные) фермы.

Только ещё не помешает мониторить перезагрузку телефона. А то пользователь перезагрузит устройство и всё, сломается его мониторинг (до момента пока он не перезапустит мониторинг)... Это если хочется почти нон-стоп и в автоматическом режиме.

1 час назад, Евгений Корепов сказал:

По поводу флага - метод RTC_WAKEUP вроде так и работает, будит телефон для выполнение задачи, но экран не включается. По крайней мере в варианте getService. У меня экран телефона всю ночь был выключен, запросы шли стабильно.

Да, точно. Видимо, я перепутал с другой задачей и другой реализацией, давно это было. (надо будет освежить знания по этой теме)

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

Только ещё не помешает мониторить перезагрузку телефона. А то пользователь перезагрузит устройство и всё, сломается его мониторинг (до момента пока он не перезапустит мониторинг)... Это если хочется почти нон-стоп и в автоматическом режиме.

С этим согласен. Но тут нужен java класс, компиляция его в jar, подключение jar к проекту - вот на это все у меня жуткая аллергия. Вчера пытался воспользоваться вашим bat-файлом, потом просто отдельными строками, в итоге психанул и все удалил :-) Особенно тяжело мне дается неясная необходимость во вложенных папках для класса, не понятно в какой именно папке запускать javac. Понимаю что создатели java любили линукс, и там засранные тысячами файлов папки, чудовищная иерархия вложенных папок и прочие чудеса считаются нормой. Но я воспитан в строгости и порядке, для меня в порядке вещей если исполняемый файл сам выясняет из какой папки был запущен и где искать свои *.ini, *.cfg, библиотеки и подобные файлы. 

Сейчас буду бороться с задвоенными вызовами будильника, видимо не до конца понимаю принципы работы сервиса в андроиде. AlarmManager вроде не при чем, в документации сказано что нельзя создать два одинаковых будильника на одно время. Или мне все же это удалось :-)

Ссылка на комментарий
  • 0
В 26.02.2017 в 13:32, Евгений Корепов сказал:

С этим согласен. Но тут нужен java класс, компиляция его в jar, подключение jar к проекту - вот на это все у меня жуткая аллергия. Вчера пытался воспользоваться вашим bat-файлом, потом просто отдельными строками, в итоге психанул и все удалил :-) Особенно тяжело мне дается неясная необходимость во вложенных папках для класса, не понятно в какой именно папке запускать javac. Понимаю что создатели java любили линукс, и там засранные тысячами файлов папки, чудовищная иерархия вложенных папок и прочие чудеса считаются нормой. Но я воспитан в строгости и порядке, для меня в порядке вещей если исполняемый файл сам выясняет из какой папки был запущен и где искать свои *.ini, *.cfg, библиотеки и подобные файлы. 

Сейчас буду бороться с задвоенными вызовами будильника, видимо не до конца понимаю принципы работы сервиса в андроиде. AlarmManager вроде не при чем, в документации сказано что нельзя создать два одинаковых будильника на одно время. Или мне все же это удалось :-)

Вам хорошо с AlarmManager, а что делать любителям iOS?

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

Вам хорошо с AlarmManager, а что делать любителям iOS?

 

Можно об этом поподробнее? На днях как раз собираюсь iOS версию делать, и там нужен будет Alarm Manager. Т.е. там его нет? Как тогда можно запускать запланированные задания? Сервис в фоне?

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

Так в том то и дело, что сервисов в iOS нет!  Безопасность.

Запланированные задания в iOS не запустить! Как сделать? Слать пуш, с призывом открыть приложение и что то совершить! :))

В iOS подход как в Android не прокатит!

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

Слать пуш, с призывом открыть приложение и что то совершить! :))

 

Офигеть. А для пуша нужно подключение к интернет верно? А для пуша нужен свой сайт на хостинге? Или можно как -то использовать сервера Apple?

Ссылка на комментарий
  • 0
  • Модераторы
5 часов назад, ENRGY сказал:

Офигеть. А для пуша нужно подключение к интернет верно? А для пуша нужен свой сайт на хостинге? Или можно как -то использовать сервера Apple?

в этой теме есть упоминание про сервис kinvey, возможно вам подойдёт

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

В MIUI вообще сервисы Delphi не запускаются.

Всем обладателям Xiaomi привет!

Отключил энергосбережение, предоставил приложению все привилегии. Смартфон ведет себя как iPhone.

Может кто-то знает как это лечится?

Redmi 4, Andorid 6.0.1, MIUI Global 8.0.

Изменено пользователем Pax Beach
Ссылка на комментарий
  • 0
В 24.03.2017 в 19:11, Pax Beach сказал:

В MIUI вообще сервисы Delphi не запускаются.

Проверил, запускает и работает (Xiaomi Redmi Note 4 MIUI Global 8.5).

Но вот наблюдаю такую проблему:

Есть сервис, который при старте делает POST-запрос и создает "будильник", для последующего перезапуска самого себя:

function TDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: integer): integer;
begin
  Result := TJService.JavaClass.START_STICKY; // тут может быть и START_NOT_STICKY - это не важно

  SendPost('post запрос до сервера');            

  PendIntent();
end;

procedure TDM.PendIntent(); 
var
  Intent: JIntent;
  PendingIntent: JPendingIntent;
begin
  Intent := TJIntent.Create;
  Intent.setAction(StringToJString('60sec'));
  Intent.setClassName(TAndroidHelper.Context,
    StringToJString('com.embarcadero.services.CabSrv'));

  PendingIntent := TJPendingIntent.JavaClass.getService(TAndroidHelper.Context,
    1, Intent, 0);

  TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP,
    getTimeAfterInSecs(60), PendingIntent); // раз в минуту вызываем сервис
end;


procedure TDM.SendPost(txt: string);
var
  aResponse: IHTTPResponse;
  aResponser: TResponser;
  sStream: TStringStream;
  aHttpClient: TNetHTTPClient;
  sList: TStringList;
begin 
  TTask.Run(
    procedure
    begin
      try
        aHttpClient := TNetHTTPClient.Create(nil);        
        aHttpClient.OnValidateServerCertificate := OnValidateServerCertificate;        
        aHttpClient.AcceptLanguage := 'ru,en;q=0.8';
        aHttpClient.ContentType := 'application/x-www-form-urlencoded';
        aHttpClient.AcceptCharset := 'utf-8';
        aHttpClient.Accept :=
          'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8';

        sStream := TStringStream.Create();
        sList := TStringList.Create;
        sList.Add('txt=' + txt);
        
        try        
          aResponse := aHttpClient.Post(Sets.Host, sList, sStream);          
        finally
          if ((sStream <> nil) and (aResponse <> nil)) then
          begin            
            Log('SendPost OK');
          end
          else
            Log('SendPost Error');
          sStream.Free;
          sList.Free;
        end;
      finally
        aHttpClient.Free;
      end;

    end);
end;

Так вот если выгрузить программу (сервис перезапускается) и выключить экран, то через несколько минут сервис не может достучаться до сервера.

except java.net.SocketTimeoutException: connect timed out

В чем может быть проблема и как ее решить?

 

 

Изменено пользователем Rusland
Ссылка на комментарий
  • 0
В 11.09.2017 в 17:09, Rusland сказал:

Проверил, запускает и работает (Xiaomi Redmi Note 4 MIUI Global 8.5).

Так вот если выгрузить программу (сервис перезапускается) и выключить экран, то через несколько минут сервис не может достучаться до сервера. В чем может быть проблема и как ее решить?

 

 

Проблема в MUI.

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

Я замучился уже с MUI, не для разработчиков ось =)

Ссылка на комментарий
  • 0
В 18.09.2017 в 14:34, Pax Beach сказал:

Потому что в MUI большой упор на энергосбережение

Переключил режим Энергосбережения с Оптимальный на Отключено и сразу проблема с коннектом пропала :D

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

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

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

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

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

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

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

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

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

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