Служба Android останавливается, когда приложение закрыто
Я запускаю сервис из своей основной активности Android следующим образом:
final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);
Когда я закрываю страницу активности, вытаскивая ее из списка последних приложений, служба перестает работать и перезапускается через некоторое время. Я не могу использовать постоянные службы с уведомлениями из-за требований к моему приложению. Как я могу заставить службу НЕ перезапускать или выключать и просто продолжать работу при выходе из приложения?
Ответы
Ответ 1
Я в той же ситуации, пока я узнал, когда приложение закрыто, сервис закрывается также потому, что он находится в одном потоке, поэтому служба должна быть в другом потоке, чтобы она не закрывалась, посмотрите на это и посмотрите, как поддерживать сервис с помощью диспетчера аварийных сигналов здесь пример http://www.vogella.com/articles/AndroidServices/article.html таким образом, что ваша служба не будет отображаться в уведомлении.
Наконец, после всех исследований, которые я сделал, я понял, что лучший выбор для долгого обслуживания - startForeground()
, потому что он сделанные для этого, и система действительно эффективно работает с вашим сервисом.
Ответ 2
Это может помочь вам. Возможно, я ошибаюсь, но мне кажется, что это связано с возвратом START_STICKY
в ваш метод onStartCommand()
. Вы можете избежать повторного вызова службы, возвращая вместо этого START_NOT_STICKY
.
Ответ 3
сделайте так, чтобы вы обменивались данными в своем "Мастере"
<service
android:name=".sys.service.youservice"
android:exported="true"
android:process=":ServiceProcess" />
то ваша служба будет запущена в другом процессе с именем ServiceProcess
если вы хотите, чтобы ваша служба никогда не умирала:
-
onStartCommand() вернуться START_STICKY
-
onDestroy() → начало
-
создать службу Deamon
-
jin → создать процесс Native Deamon, вы можете найти некоторые проекты с открытым исходным кодом на github
-
startForeground(), есть способ запуститьForeground без уведомления, google it
Ответ 4
Службы иногда довольно сложны.
Когда вы запускаете службу из какого-либо действия (или вашего процесса), служба, по сути, работает в одном процессе.
цитата из примечаний разработчика
Большая путаница в отношении класса Service фактически вращается вокруг того, что это не так:
Служба не является отдельным процессом. Сам объект службы не подразумевает, что он работает в своем собственном процессе; если не указано иное, он работает в том же процессе, что и приложение, в котором оно входит.
Служба не является нитью. Это не значит, что нужно выполнять работу основного потока (чтобы избежать ошибок, связанных с ошибками приложения).
Итак, что это означает, если пользователь удалит приложение из последних задач, он удалит ваш процесс (включая все ваши действия и т.д.).
Теперь давайте рассмотрим три сценария.
Сначала, где служба не имеет уведомления переднего плана.
В этом случае ваш процесс будет убит вместе с вашим сервисом.
Второй, где служба имеет уведомление переднего плана
В этом случае служба не будет убита, и ни один из них не будет выполняться
Третий сценарий
Если служба не имеет уведомления переднего плана, она все равно может работать, если приложение закрыто. Мы можем сделать это, запустив службу в другом процессе.
(Тем не менее, я слышал, что некоторые люди говорят, что это может не сработать, вам нужно попробовать сами)
вы можете создать службу в отдельном процессе, включив атрибут ниже
в вашем манифесте.
Android: процесс = ": yourService"
или
android: process = "yourService" имя процесса должно начинаться с нижнего регистра.
цитата из примечаний разработчика
Если имя, присвоенное этому атрибуту, начинается с двоеточия (':'), новый процесс, частный для приложения, создается, когда это необходимо, и служба запускается в этом процессе. Если имя процесса начинается с символа с нижним регистром, служба будет выполняться в глобальном процессе этого имени при условии, что у него есть разрешение на это. Это позволяет компонентам в разных приложениях совместно использовать процесс, уменьшая использование ресурсов.
вот что я собрал, если кто-то эксперт, пожалуйста, исправьте меня, если я ошибаюсь:)
Ответ 5
попробуйте это, он будет поддерживать службу в фоновом режиме.
BackServices.class
public class BackServices extends Service{
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
в MainActivity onCreate
удалите эту строку кода
startService(new Intent(getBaseContext(), BackServices.class));
Теперь служба будет работать в фоновом режиме.
Ответ 6
Основная проблема, связанная с невозможностью запуска службы при закрытии приложения, ОС Android (В некоторых ОС) убьет службу для оптимизации ресурсов. Если вы не можете перезапустить службу, вызовите будильника, чтобы запустить ресивер следующим образом: Вот весь код, Этот код будет поддерживать сервис ur.
Манифест есть,
<service
android:name=".BackgroundService"
android:description="@string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Основной манипулятор запуска активации таким образом,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
это вызовет reciver и reciver,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
И этот релаксор Alaram называет один раз, когда приложение Android открыто и когда приложение закрыто. SO служба похожа на это,
public class BackgroundService extends Service {
private String LOG_TAG = null;
@Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
Ответ 7
Лучшим решением является использование адаптера синхронизации в android для запуска службы. Создайте адаптер синхронизации и вызовите службу запуска.. внутри метода onPerformSync. для создания учетной записи синхронизации обратитесь к этой ссылке https://developer.android.com/training/sync-adapters/index.html
Почему SyncAdapter? Ответ: Потому что раньше вы запускали службу, используя свой контекст приложения. поэтому всякий раз, когда ваш процесс приложения убивается (когда вы удаляете его из диспетчера задач или ОС убиваете его из-за нехватки ресурсов), в то время ваша служба также будет удалена. SyncAdapter не будет работать в потоке приложения.. так что если u вызовет внутри него, то услуга больше не будет удалена.. если вы не напишите код, чтобы удалить его.
Ответ 8
Использование одного и того же процесса для службы и активности и START_STICKY или START_REDELIVER_INTENT в сервисе - единственный способ перезапустить службу, когда приложение перезагружается, что происходит, когда пользователь закрывает приложение, например, а также когда система решает закрыть его по соображениям оптимизации. У вас нет службы, которая будет работать постоянно без прерывания. Это по дизайну, смартфоны не предназначены для непрерывного непрерывного процесса в течение длительного периода времени. Это связано с тем, что срок службы батареи является наивысшим приоритетом. Вам необходимо спроектировать сервис, чтобы он был остановлен в любой момент.
Ответ 9
Почему бы не использовать IntentService?
IntentService открывает новую тему отдельно от основного потока и работает там, тем самым закрывая приложение, не будет его использовать
Имейте в виду, что IntentService запускает onHandleIntent(), и когда он завершает работу службы, проверьте, соответствует ли она вашим потребностям.
http://developer.android.com/reference/android/app/IntentService.html
Ответ 10
<service android:name=".Service2"
android:process="@string/app_name"
android:exported="true"
android:isolatedProcess="true"
/>
Объявите это в своем манифесте. Укажите свое имя для своего процесса и сделайте этот процесс изолированным и экспортированным.
Ответ 11
Вы должны добавить этот код в свой класс Service, чтобы он обрабатывал случай, когда ваш процесс убит
@Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
Ответ 12
Запуск службы намерения будет проще. Службы при создании потока в приложении, но все еще в приложении.
Ответ 13
В Android O вы не можете использовать сервисы для длительных фоновых операций из-за этого, https://developer.android.com/about/versions/oreo/background. Jobservice будет лучшим вариантом с реализацией Jobscheduler.
Ответ 14
Просто переопределите метод onDestroy в вашей первой видимой деятельности, например, после всплеска у вас есть домашняя страница и при перенаправлении с всплеска на главную страницу вы уже закончили всплеск. поэтому надеть уничтожить на домашней странице. и прекратите обслуживание в этом методе.