вопрос: служба уничтожена при убийстве приложения [дубликат]

Существует три примечательных сравнения между двумя различными декларациями функций, перечисленными ниже.

  1. Доступность (область действия) функции

Выполняется следующее, поскольку function add() имеет область действия до ближайшего блока:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

Следующее не работает (потому что var add= superseeds function add()).

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

Не работает, поскольку add объявлен после использования.

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}
  1. (function) .name

Имя функции function thefuncname(){} является thefuncname , когда оно объявлено таким образом.

function foobar(a, b){}

console.log(foobar.name);

var a = function foobar(){};

console.log(a.name);

В противном случае, если функция объявлена ​​как function(){} , функция .name является первой переменной, используемой для хранения функции.

var a = function(){};
var b = (function(){ return function(){} });

console.log(a.name);
console.log(b.name);

Если нет переменные, установленные для функции, то имя функции - это пустая строка ("").

console.log((function(){}).name === "");

Наконец, функция назначается для первоначального набора имени, successi переменные, заданные для функции, не меняют имя.

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);
  1. Производительность

В Google V8 и Firefox Spidermonkey может быть несколько разметок компиляции Microsecond JIST, но в итоге результат будет таким же. Чтобы убедиться в этом, давайте рассмотрим эффективность JSPerf в microbenchmarks, сравнив скорость двух фрагментов кода. Тесты JSPerf найдены здесь . И jsben.ch тесты найдены здесь . Как вы можете видеть, есть заметная разница, когда их не должно быть. Если вы действительно такой урод, как я, то это может быть более полезно, если вы попытаетесь уменьшить количество переменных и функций в области действия и, в частности, устранить полиморфизм (например, использовать одну и ту же переменную для хранения двух разных типов).

Что такое «ближайший блок»

«Ближайший блок» - ближайшая «функция» (включая асинхронные функции, функции генератора и функции асинхронного генератора). Однако интересно, что function functionName() {} ведет себя как var functionName = function() {}, когда в блоке не замыкания элементы вне указанного закрытия.

  • Обычный var add=function(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}
  • Обычный function add(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}
  • Функция

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();
  • Заявление (например, if, else, for, while, try / catch / finally, switch, do / while, with)

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}
  • Функция стрелки с var add=function()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();
  • Функция стрелки С помощью function add()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();

63
задан Bam 20 May 2013 в 14:49
поделиться

13 ответов

Я в той же ситуации, пока я узнал, когда приложение закрыто, сервис закрывается также потому, что он находится в одном потоке, поэтому служба должна быть в другом потоке, чтобы он не закрывался, посмотрите на это и посмотрите, как поддерживать сервис с диспетчером аварийных ситуаций здесь, например, http://www.vogella.com/articles/AndroidServices/article.html , так что ваша служба не будет отображаться в

Наконец, после всех исследований, которые я сделал, я понял, что лучший выбор для долгого обслуживания - startForeground() , потому что он сделан для этого и система действительно имеет дело с вашим обслуживанием.

34
ответ дан poolie 21 August 2018 в 07:41
поделиться
  • 1
    startForeground - лучший способ обойти это. – Bam 20 November 2013 в 07:41
  • 2
    @Bam У меня есть эта точная проблема. Тем не менее, моя услуга является услугой переднего плана, и она по-прежнему убивается, когда моя деятельность закрыта. Я изменил аргумент инициализации намерения из контекста getApplicationContext () в getBaseContext (), и он решил проблему. – JayB 20 January 2015 в 21:19
  • 3
    getBaseContext () работал для меня, спасибо @JayB. – code2be 4 February 2016 в 13:17
  • 4
    Можно ли использовать getBaseContext () в pendingIntent? – Kairi San 19 February 2016 в 04:17
  • 5
    вместо использования notificationManager.notify(intent.getIntExtra("notification_Id", 0), builder.build()); следует использовать startForeground(intent.getIntExtra("notification_Id, 0), builder.build());? Я использую NotificationCompat.Builder – Kairi San 19 February 2016 в 04:31

Основная проблема, связанная с невозможностью запуска службы при закрытии приложения, ОС Android (в некоторых ОС) убьет службу для оптимизации ресурсов. Если вы не можете перезапустить службу, тогда вызовите ящик тревоги, чтобы запустить ресивера, как Это полный код. Этот код будет продолжать поддерживать сервис ur [. g0]

Манифест есть,

         <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 Main Main запускает пуск аварийного вызова таким образом,

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);

это вызовет репитер и ресивер,

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");
    }
}
1
ответ дан Ajith K P 21 August 2018 в 07:41
поделиться

заставляют вас обслуживать это в вашем Mainifest

 <service
            android:name=".sys.service.youservice"
            android:exported="true"
        android:process=":ServiceProcess" />

, тогда ваша служба будет работать в другом процессе с именем ServiceProcess


, если вы хотите, чтобы ваша служба никогда не умирала:

  1. onStartCommand () return START_STICKY
  2. onDestroy () -> startself
  3. создать службу Deamon
  4. jin -> create процесс Native Deamon, вы можете найти некоторые проекты с открытым исходным кодом на github
  5. startForeground (), есть способ запуститьForeground без уведомления, google it
10
ответ дан alanban 21 August 2018 в 07:41
поделиться
  • 1
    Довольно уверен, что начало себя в onDestroy будет считаться борьбой с системой андроидов, что является плохой практикой. – Flare Cat 26 May 2017 в 21:38
  • 2
    пожалуйста, укажите код или ссылку – android_jain 8 June 2017 в 11:14

Это может вам помочь. Возможно, я ошибаюсь, но мне кажется, что это связано с возвратом START_STICKY в ваш метод onStartCommand(). Вы можете избежать повторного вызова службы, возвращая START_NOT_STICKY.

12
ответ дан Community 21 August 2018 в 07:41
поделиться
  • 1
    Фактически служба перестает работать, когда я выхожу или закрываю приложение (а затем перезагружается служба). Я не хочу, чтобы служба останавливалась / останавливалась, когда я выхожу из / закрываю приложение; Я хочу, чтобы он продолжал работать. Я считаю, что решение имеет какое-то отношение к запуску службы в отдельном процессе, но я не уверен. – Bam 20 May 2013 в 18:36
  • 2
    Работая отлично artex, спасибо – Manikandan K 23 November 2016 в 08:10

попробуйте это, он будет поддерживать службу в фоновом режиме.

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));

Теперь служба будет работать в фоновом режиме.

2
ответ дан Irshu 21 August 2018 в 07:41
поделиться
  • 1
    Проблема в том, что: когда я убиваю приложение из меню повторов, служба перезапускается (onStartCommand снова вызывается). Единственное, что помогло мне, это сделать его передним планом. – Bam 3 December 2014 в 19:05

Вы должны добавить этот код в свой класс 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);
    }
0
ответ дан Kaustubh Bhagwat 21 August 2018 в 07:41
поделиться

Службы иногда довольно сложны.

Когда вы запускаете службу из своей деятельности (или вашего процесса), служба в основном работает в одном процессе.

цитирует разработчика примечания

Большая путаница в отношении класса Service фактически вращается вокруг того, что это не так:

Служба не является отдельным процессом. Сам объект службы не подразумевает, что он работает в своем собственном процессе; если не указано иное, он выполняется в том же процессе, что и приложение, в котором оно входит.

Служба не является нитью.

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

Сначала , где служба не имеет уведомления переднего плана.

В этом случае ваш процесс будет убит вместе с вашей службой.

Второй , где служба имеет уведомление переднего плана

В этом случае служба не будет убита, и ни один из них не является процессом

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

вы можете создать службу в отдельном процессе, включив атрибут ниже в вашем манифесте.

android: process = ": yourService"

или

android: process = "yourService" имя процесса должно начинаться с нижнего case.

цитирование из примечаний разработчика

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

это то, что я собрал, если кто-то эксперт, пожалуйста, поправьте меня, если я Неправильно:)

3
ответ дан mmmcho 21 August 2018 в 07:41
поделиться
<service android:name=".Service2"
            android:process="@string/app_name"
            android:exported="true"
            android:isolatedProcess="true"
            />

Объявите это в своем манифесте. Укажите свое имя для своего процесса и сделайте этот процесс изолированным и экспортированным.

1
ответ дан Nishanth S Babu 21 August 2018 в 07:41
поделиться

Запуск службы намерения будет проще. Служба создания потока в приложении, но все еще находится в приложении.

0
ответ дан Seb 21 August 2018 в 07:41
поделиться

Почему бы не использовать IntentService?

IntentService открывает новую тему отдельно от основного потока и работает там, таким образом закрывая приложение, не будет его использовать

. Обратите внимание, что IntentService запускает onHandleIntent (), и когда он сервис закрывается, проверьте, соответствует ли он вашим потребностям. http://developer.android.com/reference/android/app/IntentService.html

0
ответ дан sharon gur 21 August 2018 в 07:41
поделиться
  • 1
    На самом деле мое требование состояло в том, чтобы всегда работать в фоновом режиме. Запуск службы в качестве службы переднего плана разрешил это для меня. – Bam 31 May 2015 в 13:48

Использование одного и того же процесса для службы и активности и START_STICKY или START_REDELIVER_INTENT в сервисе - единственный способ перезапустить службу при перезапуске приложения, которое происходит, когда пользователь закрывает приложение, например, а также когда система решает закрыть его по соображениям оптимизации. У вас нет службы, которая будет работать постоянно без прерывания. Это по дизайну, смартфоны не предназначены для непрерывного непрерывного процесса в течение длительного периода времени. Это связано с тем, что срок службы батареи является наивысшим приоритетом. Вам нужно спроектировать свой сервис, чтобы он был остановлен в любой момент.

1
ответ дан stef 21 August 2018 в 07:41
поделиться

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

-5
ответ дан user2689337 21 August 2018 в 07:41
поделиться
1
ответ дан Nishanth S Babu 1 November 2018 в 02:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: