Служба 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(), потому что он сделанные для этого, и система действительно эффективно работает с вашим сервисом.

Ответ 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 в вашей первой видимой деятельности, например, после всплеска у вас есть домашняя страница и при перенаправлении с всплеска на главную страницу вы уже закончили всплеск. поэтому надеть уничтожить на домашней странице. и прекратите обслуживание в этом методе.