Хобрук: Ваш путь к мастерству в программировании

Остановка служб в удаленных процессах

У меня есть фоновая служба с именем MyService в удаленном (конкретном для приложения) процессе с именем MyApp:MyOtherProcess. Что происходит с MyApp:MyOtherProcess и MyService, когда я смахиваю приложение?

Интерфейс Apps => Running Apps сообщает мне, что у меня 0 процессов и 1 служба. Я интерпретирую это так, что MyApp:MyOtherProcess не активен, но проснется, когда проснется MyService.

Думая, что MyService все еще запущен, я попытался остановить службу.

Остановить MyService:

Intent i = new Intent(context, MyService.class);
if (isMyOtherProcessRunning(context)) {
  //Test case: I have swiped away the application
  //Ahh, nothing is logged so I think MyService.onDestory is not invoked!
  //Is MyService still running???
  context.stopService(context, i);
} else {
  //Test case: I have not swiped away the application
  //Good, "destroying" is logged so MyService.onDestroy was invoked!
  context.stopService(context, i);
}

МойСервис:

public MyService : Service {
  @Override
  public void onCreate() {
    Log.d("MyService", "creating");
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("MyService", "starting");
    return START_REDELIVER_INTENT;
  }

  @Override
  public void onDestroy() {
    Log.d("MyService", "destroying");
  }
}

Помощник:

public boolean isMyOtherProcessRunning(Context applicationContext) {
  ActivityManager activityManager = (ActivityManager)applicationContext.getSystemService(Context.ACTIVITY_SERVICE);
  List<RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
  for(int i = 0; i < procInfos.size(); i++)
  {
    String processName = procInfos.get(i).processName;
    if(processName.equals("MyApp:MyOtherProcess")) {
      return true;
    }
  }
  return false;
}

AndroidManifest.xml:

<service android:enabled="true" android:name="com.myapp.MyService" android:process=":MyOtherProcess" />

Чтобы обойти это, я запускаю MyService и немедленно останавливаю MyService, если процесс был убит. Это похоже на плохую практику. Является ли перезапуск службы только для того, чтобы убить ее, плохой практикой? Я чувствую, что не понимаю, как MyService поддерживается, когда содержащий процесс "убит"... процесс даже уничтожается в во-первых... может ли процесс стать просто неактивным... так потерян!

Текущий обходной путь

Остановить MyService:

Intent i = new Intent(context, MyService.class);
if (isMyOtherProcessRunning(context)) {
  //Test case: I have swiped away the application
  //Ahh, nothing is logged so I think MyService.onDestory is not invoked!
  //Is MyService still running???
  i.putExtra("stopImmediately", true);
  context.stopService(context, i);
} else {
  //Test case: I have not swiped away the application
  //Good, "destroying" is logged so MyService.onDestroy was invoked!
  context.stopService(context, i);
}

МойСервис:

public MyService : Service {
  @Override
  public void onCreate() {
    Log.d("MyService", "creating");
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("MyService", "starting");
    if (intent.getBooleanExtra("stopImmediately", false)) {
      this.stopSelf();
      return START_NOT_STICKY;
    }
    return START_REDELIVER_INTENT;
  }

  @Override
  public void onDestroy() {
    Log.d("MyService", "destroying");
  }
}

Я использую Android 4.4.4 API 19 на Samsung Galaxy S5 с Genymotion версии 2.3.1.


  • я не понимаю: вы вызываете stopService, ожидая вызова onStartCommand? 26.03.2015
  • Нет, я вызываю stopService и ожидаю вызова onDestroy. 26.03.2015
  • так почему вы передаете stopImmediately дополнительно в намерении для stopService? чего именно вы хотите добиться? 26.03.2015
  • Я не понимаю, почему stopService() не вызывает onDestroy(). В качестве обходного пути я пытаюсь запустить команду (которая, кажется, будит удаленный процесс). Затем сразу после запуска команды я останавливаю ее. Мой обходной путь работает, как и ожидалось, когда вызываются onStartCommand() и onDestroy(). 26.03.2015
  • что возвращает stopService? 26.03.2015
  • О, хороший вопрос! Я никогда не проверял. Он возвращает истину. Итак, я предполагаю, что это означает, что служба остановлена, но onDestroy() никогда не вызывается? 26.03.2015
  • хммм, правда ок, ты тоже привязываешься к этому сервису? 26.03.2015
  • Я не совсем знаком с привязкой к службе. Но я так не думаю. MyService.onBind никогда не вызывается. 26.03.2015

Ответы:


1

Я думаю, IntentService поможет вашему делу. Расширьте свою службу как IntentService, а не службу, которую вы хотите автоматически остановить.

IntentService — это базовый класс для служб, которые обрабатывают асинхронные запросы (выраженные как намерения) по требованию. Клиенты отправляют запросы через вызовы startService(Intent); служба запускается по мере необходимости, обрабатывает каждое намерение по очереди, используя рабочий поток, и останавливается, когда заканчивается работа.

26.03.2015
  • IntentService кажется действительно полезным! Но нужно ли это, так как я уже в другом процессе? 26.03.2015
  • Но вы создаете сервис, не так ли? Просто создайте тип IntentService, службу, которую вы хотите остановить после выполнения работы. Это сделано для этой цели. 31.03.2015
  • Но я хочу, чтобы моя служба работала долго. 31.03.2015
  • Новые материалы

    Прогресс в технологии Трансформеров часть 3
    Многомасштабный управляющий сигнальный преобразователь для бесфазного синтеза движения (arXiv) Автор: Линтао Ван , Кун Ху , Лей Бай , Юй Дин , Ваньли Оуян , Чжиюн Ван . Аннотация:..

    Представляем поддержку компонентов Vue.js. Мгновенный HMR и многое другое.
    Хотя у FuseBox уже был плагин Vue, он был базовым и не имел многих функций, которые делали работу с Vue.js такой приятной. Однако с этим выпуском мы рады сообщить, что в FuseBox..

    Приключения в Javascript, часть 1
    Я продолжаю думать о том, чтобы писать больше, но чем больше я думаю об этом, тем меньше я это делаю. Итак, сегодня я перестал думать и начал писать. Отсюда можно только спускаться… В..

    Понимание дженериков в TypeScript: подробное руководство
    Введение TypeScript, строго типизированный надмножество JavaScript, хорошо известен своей способностью улучшать масштабируемость, удобочитаемость и ремонтопригодность приложений. Одной из..

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..