Intereting Posts
Разница между intent.setClass () и intent.setComponent () Кнопок под расширением scrollview Удалите предыдущий маркер и добавьте новый маркер в Google Map v2 AsyncTask «Только исходный поток, создавший иерархию представлений, может коснуться его представлений». Как показать определенную часть веб-страницы в веб-обозревателе с подходящим экраном для всех устройств Сбой сертификата ssl от Charles не удалось из-за сбоев сети Запросить разрешение на Android M только при таргетинге на более низкий API Как загрузить программно XML-файл макета в Android? Воспроизведение детей Принимая слишком много времени, чтобы рисовать на экране Как разместить элементы ActionBar в главной панели ActionBar и нижней панели Отсутствует api_key / текущий ключ с Google Services 3.0.0 Android-страница Curl animation NavigationView: как вставить разделитель без подгруппы? Android python scripting: GUI? Управление вводом HTML-файла с атрибутами захвата и принятия работает неправильно?

Наземное обслуживание, убитое Android

Обновление : я не нашел правильного решения проблемы. Я придумал метод автоматического повторного подключения к предыдущему устройству Bluetooth в любое время, когда соединение будет потеряно. Это не идеально, но, похоже, он работает достаточно хорошо. Мне бы хотелось услышать больше предложений по этому поводу.

У меня есть такая же проблема, как и в этом вопросе: Служба, убиваемая при сохранении блокировки после пробуждения, и после вызова startForeground, включая устройство (Asus Transformer), время до остановки службы (30-45 минут), использование Блокировка входа в систему, использование startForeground () и тот факт, что проблема не возникает, если приложение открыто, когда экран отключается.

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

Согласно ответу в связанном вопросе, startForeground () «уменьшает вероятность того, что служба будет убита, но не предотвратит ее». Я понимаю, что так было, однако я видел много примеров других приложений, которые не имеют этой проблемы (например, Tasker).

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

Я вижу это в своем logcat всякий раз, когда служба остановлена:

ActivityManager: No longer want com.howettl.textab (pid 32321): hidden #16 WindowManager: WIN DEATH: Window{40e2d968 com.howettl.textab/com.howettl.textab.TexTab paused=false ActivityManager: Scheduling restart of crashed service com.howettl.textab/.TexTabService in 5000ms 

EDIT: Следует также отметить, что это не похоже на другое устройство, с которым я подключен: HTC Legend работает с Cyanogen

EDIT: Вот результат работы службы adb shell dumpsys activity services :

 * ServiceRecord{40f632e8 com.howettl.textab/.TexTabService} intent={cmp=com.howettl.textab/.TexTabService} packageName=com.howettl.textab processName=com.howettl.textab baseDir=/data/app/com.howettl.textab-1.apk resDir=/data/app/com.howettl.textab-1.apk dataDir=/data/data/com.howettl.textab app=ProcessRecord{40bb0098 2995:com.howettl.textab/10104} isForeground=true foregroundId=2 foregroundNoti=Notification(contentView=com.howettl.textab/0x1090087 vibrate=null,sound=null,defaults=0x0,flags=0x6a) createTime=-25m42s123ms lastActivity=-25m42s27ms executingStart=-25m42s27ms restartTime=-25m42s124ms startRequested=true stopIfKilled=false callStart=true lastStartId=1 Bindings: * IntentBindRecord{40a02618}: intent={cmp=com.howettl.textab/.TexTabService} binder=android.os.BinderProxy@40a9ff70 requested=true received=true hasBound=true doRebind=false * Client AppBindRecord{40a3b780 ProcessRecord{40bb0098 2995:com.howettl.textab/10104}} Per-process Connections: ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8} All Connections: ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8} 

И вывод adb shell dumpsys activity :

 * TaskRecord{40f5c050 #23 A com.howettl.textab} numActivities=1 rootWasReset=false affinity=com.howettl.textab intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.howettl.textab/.TexTab} realActivity=com.howettl.textab/.TexTab lastActiveTime=4877757 (inactive for 702s) * Hist #1: ActivityRecord{40a776c8 com.howettl.textab/.TexTab} packageName=com.howettl.textab processName=com.howettl.textab launchedFromUid=2000 app=ProcessRecord{40bb0098 2995:com.howettl.textab/10104} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.howettl.textab/.TexTab } frontOfTask=true task=TaskRecord{40f5c050 #23 A com.howettl.textab} taskAffinity=com.howettl.textab realActivity=com.howettl.textab/.TexTab base=/data/app/com.howettl.textab-1.apk/data/app/com.howettl.textab-1.apk data=/data/data/com.howettl.textab labelRes=0x7f060000 icon=0x7f020000 theme=0x0 stateNotNeeded=false componentSpecified=true isHomeActivity=false configuration={ scale=1.0 imsi=0/0 loc=en_CA touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=6} launchFailed=false haveState=true icicle=Bundle[mParcelledData.dataSize=1644] state=STOPPED stopped=true delayedResume=false finishing=false keysPaused=false inHistory=true visible=false sleeping=true idle=true fullscreen=true noDisplay=false immersive=false launchMode=2 frozenBeforeDestroy=false thumbnailNeeded=false connections=[ConnectionRecord{40a76920 com.howettl.textab/.TexTabService:@40b998b8}] 

 Proc #15: adj=prcp /F 40e75070 959:android.process.acore/10006 (provider) com.android.providers.contacts/.ContactsProvider2<=Proc{40bb0098 2995:com.howettl.textab/10104} Proc #16: adj=bak+2/F 40bb0098 2995:com.howettl.textab/10104 (foreground-service) 

Кажется, они показывают, что служба работает на переднем плане.

Solutions Collecting From Web of "Наземное обслуживание, убитое Android"

Оки Доки. Я прошел через ад и вернулся к этой проблеме. Вот как это делается. Есть ошибки. В этой публикации описывается, как анализировать ошибки в реализации и решать проблемы.

Просто подведем итог, вот как все должно работать. Запуск сервисов будет регулярно очищаться и заканчиваться каждые 30 минут или около того. Службы, которые хотят оставаться в живых дольше, чем это, должны вызвать Service.startForeground, который размещает уведомление на панели уведомлений, чтобы пользователи знали, что ваша служба постоянно работает и потенциально сосать время автономной работы. Только 3 процесса обслуживания могут назначать себя как услуги переднего плана в любой момент времени. Если есть более трех услуг переднего плана, Android назначит самую старую услугу в качестве кандидата на очистку и завершение.

К сожалению, в Android существуют ошибки в отношении приоритезации служб переднего плана, которые запускаются различными комбинациями флагов привязки сервисов. Несмотря на то, что вы правильно назначили свое обслуживание в качестве услуги переднего плана, Android может прекратить службу в любом случае, если какие-либо подключения к службам в вашем процессе когда-либо были сделаны с определенными комбинациями флагов привязки. Подробности приведены ниже.

Обратите внимание, что очень немногие службы должны быть передними службами. Как правило, вам нужно быть только передним, если у вас есть постоянно действующее или долгое подключение к Интернету, которое может быть включено и выключено или отменено пользователями. Примеры служб, которые требуют статуса переднего плана: серверы UPNP, длительная загрузка очень больших файлов, синхронизация файловых систем с помощью Wi-Fi и воспроизведение музыки.

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

Проверяя ящики на хорошо известных требованиях (например, вызов Service.startForeground), следующее место для поиска – это флаги, которые вы используете в вызовах Context.bindService. Флаги, используемые для привязки, влияют на приоритет целевого процесса обслуживания различными неожиданными способами. В частности, использование определенных флагов привязки может привести к тому, что Android некорректно понизит ваш приоритетный сервис до обычной службы. Код, используемый для назначения приоритета процесса, был сильно изменен. Примечательно, что в API 14+ есть версии, которые могут вызывать ошибки при использовании старых флагов привязки; И в 4.2.1 есть определенные ошибки.

Друг во всем этом – это утилита sysdump, которая может использоваться для определения того, какой приоритет менеджер активности назначил вашему сервису, и выявить случаи, когда он назначил неправильный приоритет. Запустите службу и выполните следующую команду из командной строки на вашем хост-компьютере:

Процессы активности dbsys оболочки adb> tmp.txt

Используйте блокнот (не wordpad / write), чтобы изучить содержимое.

Сначала убедитесь, что вы успешно выполнили свою работу в режиме переднего плана. Первый раздел файла dumpsys содержит описание свойств ActivityManager для каждого процесса. Найдите строку, подобную следующей, которая соответствует вашему приложению в первом разделе файла dumpsys:

APP UID 10068 ProcessRecord {41937d40 2205: tunein.service / u0a10068}

Убедитесь, что foregroundServices = true в следующем разделе. Не беспокойтесь о скрытых и пустых настройках; Они описывают состояние деятельности в этом процессе и, похоже, не имеют особого отношения к процессам с услугами в них. Если foregroundService неверен, вам нужно вызвать Service.startForeground, чтобы сделать его истинным.

Следующее, что вам нужно посмотреть, это раздел в конце файла под названием «Список процессов LRU (отсортированный по oom_adj):». Записи в этом списке позволяют определить, действительно ли Android классифицировала ваше приложение как службу переднего плана. Если ваш процесс находится в нижней части этого списка, это главный кандидат на итоговое истребление. Если ваш процесс находится в верхней части списка, он практически не поддается разрушению.

Давайте посмотрим на строку в этой таблице:

  Proc #31: adj=prcp /FS trm= 0 2205:tunein.service/u0a10068 (fg-service) 

Это пример службы переднего плана, которая сделала все правильно. Ключевым полем здесь является поле «adj =». Это указывает приоритет, который ваш процесс был назначен ActivityManagerService после того, как все было сказано. Вы хотите, чтобы это было «adj = prcp» (видимая функция переднего плана); Или «adj = vis» (видимый процесс с активностью) или «fore» (процесс с активностью переднего плана). Если это «adj = svc» (процесс обслуживания) или «adj = svcb» (устаревшая услуга?) Или «adj = bak» (пустой фоновый процесс), тогда ваш процесс является вероятным кандидатом на прекращение и будет прекращен Не реже, чем каждые 30 минут, даже если нет никакого давления на восстановление памяти. Остальные флаги на линии – это в основном диагностическая отладочная информация для инженеров Google. Решения о прекращении принимаются на основе полей adj. Вкратце, / FS указывает службу переднего плана; / FA указывает на процесс переднего плана с активностью. / B указывает фоновое обслуживание. Метка в конце указывает общее правило, согласно которому процессу присваивается приоритет. Обычно он должен соответствовать полю adj =; Но значение adj = может быть скорректировано вверх или вниз в некоторых случаях из-за флагов привязки при активных привязках к другим службам или действиям.

Если вы столкнулись с ошибкой с флагами привязки, строка dumpsys будет выглядеть так:

  Proc #31: adj=bak /FS trm= 0 2205:tunein.service/u0a10068 (fg-service) 

Обратите внимание, что значение поля adj неправильно установлено на «adj = bak» (пустой фоновый процесс), что примерно соответствует «пожалуйста, пожалуйста, прекратите меня сейчас, чтобы я мог закончить это бессмысленное существование» для целей очистки процесса. Также обратите внимание на флаг (fg-service) в конце строки, который указывает, что для определения параметра «adj» использовались «правила наземной службы». Несмотря на то, что правила fg-service были использованы, этому процессу была назначена настройка adj «Bak», и он не будет долго жить. Положительно, это ошибка.

Поэтому цель состоит в том, чтобы гарантировать, что ваш процесс всегда получает «adj = prcp» (или лучше). И метод достижения этой цели состоит в том, чтобы настроить флаги привязки, пока вам не удастся избежать ошибок при назначении приоритета.

Вот ошибки, о которых я знаю. (1) Если ЛЮБОЙ сервис или деятельность когда-либо связаны с сервисом с использованием Context.BIND_ABOVE_CLIENT, вы рискуете, что параметр adj = будет понижен до «bak», даже если эта привязка больше не активна. Это особенно верно, если у вас также есть привязки между службами. Явная ошибка в источниках 4.2.1. (2) Определенно никогда не используйте BIND_ABOVE_CLIENT для привязки сервиса к сервису. Не используйте его для подключения к работе. Флаг, используемый для реализации поведения BIND_ABOVE_CLIENT, по-видимому, устанавливается на основе каждого процесса, а не для каждого соединения, поэтому он запускает ошибки с привязками к сервису, даже если нет активной активности для обслуживания Привязка с установленным флагом. Также возникают проблемы с установлением приоритета, когда в процессе присутствуют несколько служб с привязками к сервису. Использование Context.BIND_WAIVE_PRIORITY (API 14) в привязке к сервисам может помочь. Context.BIND_IMPORTANT, по-видимому, является более или менее хорошей идеей при привязке из Activity к службе. Это приводит к тому, что приоритет процесса превышает один уровень выше, если активность находится на переднем плане, без какого-либо очевидного вреда, когда действие приостановлено или закончено.

Но в целом стратегия состоит в том, чтобы настроить флаги bindService, пока sysdump не покажет, что ваш процесс получил правильный приоритет.

Для моих целей, используя Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT для привязок к действию для обслуживания и Context.BIND_AUTO_CREATE | Контекст.BIND_WAIVE_PRIORITY для привязок сервисов к сервисам, кажется, делает правильные вещи. Ваш пробег может отличаться.

Мое приложение довольно сложно: два фоновых сервиса, каждый из которых может независимо поддерживать состояния обслуживания переднего плана, а также третью, которая также может принимать состояние обслуживания переднего плана; Две из этих услуг связаны друг с другом условно; Третий привязывается к первому, всегда. Кроме того, Activites запускается в отдельном процессе (делает анимацию более плавной). Выполнение действий и служб в том же процессе, похоже, не имело никакого значения.

Реализация правил для процессов очистки (и исходный код, используемый для генерации содержимого файлов sysdump), можно найти в основном файле андроида

 frameworks\base\services\java\com\android\server\am\ActivityManagerService.java. 

Удачи.

PS: Вот интерпретация строк sysdump для Android 5.0. Я не работал с ними, поэтому сделай из них то, что пожелаешь. Я считаю, что вы хотите, чтобы 4 были «A» или «S», а 5 – «IF» или «IB», а 1 – как можно ниже (вероятно, ниже 3, поскольку только 3 три процесса обслуживания переднего плана поддерживаются активными В конфигурации по умолчанию).

 Example: Proc # : prcp F/S/IF trm: 0 31719: neirotech.cerebrum.attention:blePrcs/u0a77 (fg-service) Format: Proc # {1}: {2} {3}/{4}/{5} trm: {6} {7}: {8}/{9} ({10} 1: Order in list: lower is less likely to get trimmed. 2: Not sure. 3: B: Process.THREAD_GROUP_BG_NONINTERACTIVE F: Process.THREAD_GROUP_DEFAULT 4: A: Foreground Activity S: Foreground Service ' ': Other. 5: -1: procState = "N "; ActivityManager.PROCESS_STATE_PERSISTENT: procState = "P "; ActivityManager.PROCESS_STATE_PERSISTENT_UI:procState = "PU"; ActivityManager.PROCESS_STATE_TOP: procState = "T "; ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: procState = "IF"; ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: procState = "IB"; ActivityManager.PROCESS_STATE_BACKUP:procState = "BU"; ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: procState = "HW"; ActivityManager.PROCESS_STATE_SERVICE: procState = "S "; ActivityManager.PROCESS_STATE_RECEIVER: procState = "R "; ActivityManager.PROCESS_STATE_HOME: procState = "HO"; ActivityManager.PROCESS_STATE_LAST_ACTIVITY: procState = "LA"; ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: procState = "CA"; ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: procState = "Ca"; ActivityManager.PROCESS_STATE_CACHED_EMPTY: procState = "CE"; {6}: trimMemoryLevel {8} Process ID. {9} process name {10} appUid 

Если он говорит «больше не хочет …», то этот процесс не имеет активной в нем службы, которая в настоящее время находится в состоянии startForeground (). Убедитесь, что ваш вызов на самом деле преуспел, – что вы видите уведомление отправлено, в журнале нет сообщений, жалующихся на что угодно и т. Д. Также используйте «службы активности dumpsys оболочки adb», чтобы посмотреть на Состояние вашей службы и убедитесь, что оно действительно отмечено как передний план. Кроме того, если это правильно, то в выводе «Действия adb shell dumpsys» вы увидите в разделе, показывающем, что OOM соответствует процессам, которые ваш процесс находится сейчас на уровне переднего плана из-за этой службы.