Android: сохранение фоновой службы (предотrotation процесса смерти)

У меня есть служба, которая определяется как:

public class SleepAccelerometerService extends Service implements SensorEventListener 

По сути, я делаю приложение, которое контролирует активность акселерометра по разным причинам, в то время как пользователь спит со своим телефоном / устройством на кровати. Это долговременное обслуживание, которое НЕ ДОЛЖНО быть убито ночью. В зависимости от того, сколько фоновых приложений и периодических процессов происходит ночью, андроид иногда убивает мой процесс, тем самым заканчивая мой сервис. Пример:

 10-04 03:27:41.673: INFO/ActivityManager(1269): Process com.androsz.electricsleep (pid 16223) has died. 10-04 03:27:41.681: INFO/WindowManager(1269): WIN DEATH: Window{45509f98 com.androsz.electricsleep/com.androsz.electricsleep.ui.SleepActivity paused=false} 

Я не хочу заставлять пользователя иметь «SleepActivity» или какую-то другую активность в моем приложении в качестве переднего плана. Я не могу запускать свою службу периодически, потому что она постоянно перехватывает onSensorChanged.

Какие-нибудь советы? Исходный код находится здесь: http://code.google.com/p/electricsleep/

Для Android 2.0 или более поздней версии вы можете использовать метод startForeground() для запуска службы на переднем плане.

В документации говорится следующее :

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

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

Вам нужно будет предоставить Notification методу, который отображается в панели уведомлений в разделе «Продолжить».

Когда вы связываете свою Службу с деятельностью с BIND_AUTO_CREATE, ваша служба убивается сразу после того, как ваша деятельность разрушена и несвязана. Это не зависит от того, как вы внедрили метод UnBSind Services, он все равно будет убит.

Другой способ – запустить службу с помощью метода startService из вашей деятельности. Таким образом, даже если ваша активность будет уничтожена, ваш сервис не будет уничтожен или даже приостановлен, но вы должны приостановить / уничтожить его самостоятельно с помощью stopSelf / stopService, когда это необходимо.

Как уже указывал Дэйв , вы можете запустить свой Service с приоритетом переднего плана. Но эта практика должна использоваться только тогда, когда это абсолютно необходимо, т. Е. Когда это вызовет плохой пользовательский опыт, если Служба будет убита Android. Это то, что на самом деле означает «передний план»: ваше приложение каким-то образом находится на переднем плане, и пользователь сразу заметил его, если он был убит (например, потому, что он воспроизводил песню или видео).

В большинстве случаев запрашивать приоритет переднего плана для вашего Сервиса является контрпродуктивным!

Почему это? Когда Android решает убить Service , он делает это, потому что ему не хватает ресурсов (обычно RAM). Основываясь на разных classах приоритетов, Android решает, какие запущенные процессы и включенные сервисы прекращаются, чтобы освободить ресурсы. Это здоровый процесс, который вы хотите добиться, чтобы пользователь имел приятный опыт. Если вы запросите приоритет переднего плана, без веской причины, просто чтобы ваш сервис не был убит, это, скорее всего, вызовет плохой пользовательский опыт. Или вы можете гарантировать, что ваш сервис остается в минимальном потреблении ресурсов и не имеет утечек памяти? 1

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

Изображение, которое вы хотите написать клиенту XMPP для Android. Если вы запрашиваете приоритет переднего плана для Service который содержит ваше соединение XMPP? Определенно нет, нет абсолютно никаких оснований для этого. Но вы хотите использовать START_STICKY качестве флага возврата для метода onStartCommand вашего сервиса. Чтобы ваша служба была остановлена, когда есть давление в ресурсе, и возобновляется, как только ситуация вернется к норме.

1 : Я уверен, что многие приложения Android имеют утечки памяти. Это то, о чем не беспокоит случайный (рабочий) программист.

У меня была аналогичная проблема. На некоторых устройствах через некоторое время Android убивает мое обслуживание и даже startForeground () не помогает. И моему клиенту это не нравится. Мое решение – использовать class AlarmManager, чтобы убедиться, что служба работает, когда это необходимо. Я использую AlarmManager для создания своего рода сторожевого таймера. Он проверяет время от времени, если служба должна быть запущена и перезапустить ее. Также я использую SharedPreferences, чтобы сохранить флаг, должен ли быть запущен сервис.

Создание / отключение моего сторожевого таймера:

 void setServiceWatchdogTimer(boolean set, int timeout) { Intent intent; PendingIntent alarmIntent; intent = new Intent(); // forms and creates appropriate Intent and pass it to AlarmManager intent.setAction(ACTION_WATCHDOG_OF_SERVICE); intent.setClass(this, WatchDogServiceReceiver.class); alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am=(AlarmManager)getSystemService(Context.ALARM_SERVICE); if(set) am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, alarmIntent); else am.cancel(alarmIntent); } 

Получение и обработка намерения с сторожевого таймера:

 /** this class processes the intent and * checks whether the service should be running */ public static class WatchDogServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(ACTION_WATCHDOG_OF_SERVICE)) { // check your flag and // restart your service if it's necessary setServiceWatchdogTimer(true, 60000*5); // restart the watchdogtimer } } } 

Действительно, я использую WakefulBroadcastReceiver вместо BroadcastReceiver . Я дал вам код с BroadcastReceiver, чтобы упростить его.

http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT

public static final int BIND_ABOVE_CLIENT – добавлен в уровень API 14

Флаг для bindService(Intent, ServiceConnection, int) : указывает, что привязка клиента к этой службе считает услугу более важной, чем сама приложение. Когда установлено, платформа попытается убить убийцу из памяти, прежде чем он убьет службу, к которой она привязана, хотя это не гарантируется.

Другие флаги той же группы: BIND_ADJUST_WITH_ACTIVITY, BIND_AUTO_CREATE, BIND_IMPORTANT, BIND_NOT_FOREGROUND, BIND_WAIVE_PRIORITY.

Обратите внимание, что значение BIND_AUTO_CREATE изменилось в ICS, а старые приложения, которые не указывают BIND_AUTO_CREATE , автоматически будут иметь для них флаги BIND_WAIVE_PRIORITY и BIND_ADJUST_WITH_ACTIVITY .

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

Я работаю над приложением и сталкиваюсь с проблемой убийства моего сервиса при убийстве приложения. Я исследовал Google и обнаружил, что должен сделать это на переднем плане. Ниже приведен код:

 public class UpdateLocationAndPrayerTimes extends Service { Context context; @Override public void onCreate() { super.onCreate(); context = this; } @Override public int onStartCommand(Intent intent, int flags, int startId) { StartForground(); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } private void StartForground() { LocationChangeDetector locationChangeDetector = new LocationChangeDetector(context); locationChangeDetector.getLatAndLong(); Notification notification = new NotificationCompat.Builder(this) .setOngoing(false) .setSmallIcon(android.R.color.transparent) //.setSmallIcon(R.drawable.picture) .build(); startForeground(101, notification); } } 

хмель, что это может помочь !!!!

Interesting Posts

Закрепить JSF для обновления страницы / просмотра / формы при открытии через ссылку или кнопку возврата

Перенаправление URL-адреса IIS7 из корневого каталога в подкаталог

Как создать пользовательский атрибут AuthorizeAttribute в ASP.NET Core?

Java, Как получить количество сообщений в теме в apache kafka

Считайте уникальные значения с помощью pandas на группы

подсчитать количество вызовов пункта

Может кто-нибудь объяснить этот код шаблона, который дает мне размер массива?

Сервис, запускающий процесс, не отображает GUI C #

Когда CRC более подходит для использования, чем MD5 / SHA1?

при масштабировании элемента с масштабом css3 он становится пиксельным до тех пор, пока анимация не будет завершена. Я анимация элемента с границей

Алгоритм упрощения десятичных дробей

Тестирование модуля ASP.Net MVC Авторизовать атрибут для проверки перенаправления на страницу входа в систему

Поддержка streamового запроса WebAPI

JSON.NET: зачем использовать JToken – когда-либо?

Как масштабировать streamовое bitmap на месте, не читая сначала все изображение?

Давайте будем гением компьютера.