Intereting Posts
Ошибка Gradle Sync не удалось найти ограничение-макет: 1.0.0-alpha2 Настройка каталога настраиваемых ресурсов для модульного тестирования в Android Studio InApp Billing: java.lang.SecurityException Требуется READ_PHONE_STATE Программно индексировать файлы hprof памяти разбора Есть ли уникальный идентификатор устройства Android? Firebase и Crashlytics – Какой из них использовать? Возможно ли анимировать диалоговое окно «Диалог»? Воспроизведение по умолчанию мягкой клавиатуры при нажатии кнопок в android Как отправить стоимость через намерение после завершения деятельности Что такое «Контекст» на Android? AutoCompleteTextView скрывает автоматические предложения Как я могу добавить facebook SDK в проект Android? Android Build – эмулятор, застрявший на логотипе Android Android: как добавить приложение в список «Поделиться через» для фотоаппарата Использование BottomBar предотвращает открытие фрагментов?

Как мы можем не допустить, чтобы Служба была убита ОС?

Я использую Service в своем приложении, и его нужно запустить до тех пор, пока мое приложение не будет удалено, но проблема в том, что он убит ОС.

Как мы можем предотвратить его уничтожение ОС? Или, если он будет убит, мы снова перезапустим эту службу программным путем?

Solutions Collecting From Web of "Как мы можем не допустить, чтобы Служба была убита ОС?"

Вы можете запустить службу на переднем плане, используя startForeground () .

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

Но имейте в виду, что служба переднего плана должна предоставлять уведомление для строки состояния (см. Здесь ) и что уведомление не может быть отклонено, если служба не остановлена ​​или не удалена с переднего плана.

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

Я был озадачен тем же самым вопросом к вам недавно. Но теперь я нашел хорошее решение. Прежде всего, вы должны знать, что даже ваша служба была убита ОС, метод onCreate вашей службы будет вызван ОС за короткое время. Таким образом, вы можете сделать сопутствующий метод onCreate следующим образом:

 @Override public void onCreate() { Log.d(LOGTAG, "NotificationService.onCreate()..."); //start this service from another class ServiceManager.startService(); } @Override public void onStart(Intent intent, int startId) { Log.d(LOGTAG, "onStart()..."); //some code of your service starting,such as establish a connection,create a TimerTask or something else } 

Содержимое «ServiceManager.startService ()»:

 public static void startService() { Log.i(LOGTAG, "ServiceManager.startSerivce()..."); Intent intent = new Intent(NotificationService.class.getName()); context.startService(intent); } 

Тем не менее, это решение просто доступно для того, чтобы ваша служба была убита GC. Иногда наша служба может быть убита пользователем с помощью Program Manager. В этой ситуации ваши попытки будут убиты, и ваш сервис никогда не будет повторно создан. Таким образом, ваша служба не может быть перезапущена. Но хорошей новостью является то, что, когда премьер-министр убивает вашу службу, он будет называть ваш метод onDestroy. Поэтому мы можем что-то сделать с этим методом.

  @Override public void onDestroy() { Intent in = new Intent(); in.setAction("YouWillNeverKillMe"); sendBroadcast(in); Log.d(LOGTAG, "onDestroy()..."); } 

Строка «YouWillNeverKillMe» – это обычное действие. Самое главное в этом методе – не добавлять код перед отправкой трансляции. Поскольку система не будет ждать завершения onDestroy (), вы должны отправить рассылку как можно скорее. Затем зарегистрируйте приемник в файле manifestast.xml:

 <receiver android:name=".app.ServiceDestroyReceiver" > <intent-filter> <action android:name="YouWillNeverKillMe" > </action> </intent-filter> </receiver> 

Наконец, создайте BroadcastReceiver и запустите службу в методе onReceive:

 @Override public void onReceive(Context context, Intent intent) { Log.d(LOGTAG, "ServeiceDestroy onReceive..."); Log.d(LOGTAG, "action:" + intent.getAction()); Log.d(LOGTAG, "ServeiceDestroy auto start service..."); ServiceManager.startService(); } 

Надеюсь, это будет полезно для вас, и извините мой плохой письменный английский.

Переопределите метод onStartCommand() в своем классе обслуживания и просто верните START_STICKY (как указано в «Не пустое»). Это все, что вам нужно. Если процесс, который запускает вашу службу, убивается (например, из-за низкого состояния памяти), система Android перезапустит ее автоматически (обычно с некоторой задержкой, например 5 секунд).

Не используйте onStart() больше, как предлагается в другом ответе, это устарело.

использование

 @Override public int onStartCommand(Intent intent, int flags, int startId) { //**Your code ** // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } 

Ref Документация жизненного цикла службы.

Измените добавленный метод.

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

  1. Используйте функцию (StartServicesActivity) для запуска службы (FileObserverService) в качестве службы Foreground.
  2. Используйте класс BroadcastReceiver (в примере CommonReceiver), чтобы перезапустить службу в некоторых особых ситуациях и в случае ее убийства.

Я использовал этот код в своем приложении «Автоматически отправлять фотографии по электронной почте» https://play.google.com/store/apps/details?id=com.alexpap.EmailPicturesFree

Вот класс CommonReceiver.

 public class CommonReceiver extends BroadcastReceiver { public void onReceive(Context paramContext, Intent paramIntent) { paramContext.startService(new Intent(paramContext, FileObserverService.class)); } } 

Вот его определение в AndroidManifest.xml непосредственно перед закрытием тега приложения.

 <receiver android:name="com.alexpap.services.CommonReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.USER_PRESENT"/> </intent-filter> </receiver> 

Запустите службу в StartServicesActivity.

 Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class); StartServicesActivity.this.startService(iFileObserver); 

Здесь используется метод onStartCommand ().

 public int onStartCommand(Intent intent, int flags, int startId) { int res = super.onStartCommand(intent, flags, startId); /*** Put your code here ***/ startServiceForeground(intent, flags, startId); return Service.START_STICKY; } public int startServiceForeground(Intent intent, int flags, int startId) { Intent notificationIntent = new Intent(this, StartServicesActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new NotificationCompat.Builder(this) .setContentTitle("File Observer Service") .setContentIntent(pendingIntent) .setOngoing(true) .build(); startForeground(300, notification); return START_STICKY; } 

Я протестировал этот код с помощью приложения Task Killer, и каждый раз, когда служба была убита, она была перезапущена почти сразу (выполняет onStartCommand ()). Он также перезапускается при каждом включении телефона и после перезагрузки. Я использую этот код в своем приложении, который отправляет по электронной почте все изображения, которые вы берете с помощью своего телефона, для предварительного рассылки списка электронных писем. Отправляющее электронное письмо и список получающих электронных писем устанавливаются в другом действии и сохраняются в общих предпочтениях. Я взял около 100 фотографий за несколько часов, и все они были отправлены правильно, чтобы получать электронные письма.

 @Override public void onDestroy() { super.onDestroy(); startService(new Intent(this, YourService.class)); } 

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

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

 Intent iFileObserver = new Intent(StartServicesActivity.this, FileObserverService.class); PendingIntent pendingIntentFileObserver = PendingIntent.getService(StartServicesActivity.this, 0, iFileObserver, 0); AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE); Date now = new Date(); //start every 5 seconds alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, now.getTime(), 5*1000, pendingIntentFileObserver); 

И здесь находится onStartCommand () службы.

 //class variable public static boolean isStarted = false; public int onStartCommand(Intent intent, int flags, int startId) { int res = super.onStartCommand(intent, flags, startId); //check if your service is already started if (isStarted){ //yes - do nothing return Service.START_STICKY; } else { //no isStarted = true; } /**** the rest of your code ***/ return Service.START_STICKY; } 

Насколько я знаю, onDestroy() будет вызываться только тогда, когда служба явно остановлена ​​(Force Stop). Но этот метод не будет вызван в случае, если служба будет убита OS / swiping в списке Recent Apps. В этих случаях onTaskRemoved(Intent) другой обработчик событий с именем onTaskRemoved(Intent) . Это связано с дефектом в Android 4.3-4.4 по ссылке здесь . Попробуйте использовать приведенный ниже код:

 public void onTaskRemoved(Intent intent){ super.onTaskRemoved(intent); Intent intent=new Intent(this,this.getClass()); startService(intent); } 

Сначала создайте службу в другом процессе и напишите вещатель, который работает в рекурсии через промежутки времени

 protected CountDownTimer rebootService = new CountDownTimer(9000, 9000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { sendBroadcast(reboot); this.start(); Log.d(TAG, "rebootService sending PREVENT AUTOREBOT broadcast"); } }; 

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

 protected static class ServiceAutoRebooter extends BroadcastReceiver { private static ServiceAutoRebooter instance = null; private RebootTimer rebootTimer = null; private static ServiceAutoRebooter getInstance() { if (instance == null) { instance = new ServiceAutoRebooter(); } return instance; } public class RebootTimer extends CountDownTimer { private Context _context; private Intent _service; public RebootTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { _context.startService(_service); this.cancel(); Log.d(TAG, "Service AutoRebooted"); } } @Override public void onReceive(Context context, Intent intent) { if (rebootTimer == null) { Log.d(TAG, "rebootTimer == null"); rebootTimer = new RebootTimer(10000, 10000); rebootTimer._context = context; Intent service = new Intent(context, SomeService.class); rebootTimer._service = service; rebootTimer.start(); } else { rebootTimer.cancel(); rebootTimer.start(); Log.d(TAG, "rebootTimer is restarted"); } } } 

Служба будет автоматически перезагружена, если истечет время на RebootTimer (основной процесс), что означает, что передача «ПРЕДОСТЕРЕЖЕНИЕ АВТОБУТОРА» из службы не наступила

Я нашел решение … поздно ответить, но я хотел ответить …

Мы можем отправить широковещательную рассылку в ondestroy службы и создать приемник, который получает широковещательную передачу, и снова запускает сервис … когда он уничтожается по каким-либо причинам …

PLS попробовать следующее:

 final Messenger mMessenger = new Messenger(new IncomingHandler()); class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { default: super.handleMessage(msg); } } } @Override public void onCreate() { super.onCreate(); makeServiceForeground(); } @Override public IBinder onBind(Intent arg0) { return mMessenger.getBinder(); } private void makeServiceForeground() { IActivityManager am = ActivityManagerNative.getDefault(); try { am.setProcessForeground(onBind(null), android.os.Process.myPid(), true); } catch (RemoteException e) { Log.e("", "cant set to foreground" + e.toString()); } } 

Также нужно добавить в manifest.xml

 <uses-permission android:name="android.permission.SET_PROCESS_LIMIT"/>