Как получить контекст в сервисе (не applicationContext) - PullRequest
0 голосов
/ 02 мая 2018

Можно ли ссылаться на контекст в сервисе, но не использовать контекст приложения?

Я пытаюсь добиться возможности показывать закусочную из сервиса, когда что-то происходит. Это должно быть сделано в НЕСКОЛЬКИХ действиях. Для этого мне нужен контекст, а затем обратиться к нему, чтобы получить представление с помощью этой строки:

View rootView = ((Activity)context).getWindow().getDecorView().findViewById(android.R.id.content)

Я делаю это в моем сервисе:

class MyService : Service() {

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
//TODO do something useful

val view: View = (this.applicationContext as Activity).window.decorView.findViewById(android.R.id.content)
Timber.d("some jobe done")
return Service.START_NOT_STICKY
  }

override fun onBind(intent: Intent): IBinder? {
//TODO for communication return IBinder implementation
   return null
 }
}

Однако я получаю сообщение об ошибке при обращении к контексту приложения и приведению его к Activty:

Caused by: java.lang.ClassCastException: com.myapp.Application cannot be cast to android.app.Activity

Можно ли справиться с этим правильно (ссылаясь на мой вариант использования)?

1 Ответ

0 голосов
/ 02 мая 2018

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

Это не очень хорошая идея. Например, он не относится к сценарию, в котором у вас нет текущих действий.

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

Нет, вам понадобится объект Activity, как вы видите по своему составу.

Можно ли справиться с этим должным образом (ссылаясь на мой вариант использования)?

Не так, как вы подходите к проблеме.

Ваша ситуация такова: служба обнаруживает какое-то событие, и служба хотела бы сообщить пользователю об этом событии. Есть две возможности:

  • У вас есть видимое действие, и затем это действие может позволить пользователю узнать о событии некоторыми подходящими средствами (например, снэк-баром)

  • У вас нет видимой активности, и в этом случае служба может выдать уведомление или, возможно, просто отбросить событие (если нет необходимости уведомлять пользователя об этом, если пользователь не в интерфейсе приложения)

Типичным подходом к этой проблеме является использование некоторой формы шины событий (LocalBroadcastManager, EventBus greenrobot или любое количество реализаций шины событий на основе RxJava):

  • Служба публикует событие в автобусе

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

  • Если мероприятие получает событие, оно показывает снэк-бар (или что-то еще) пользователю

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

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

Этот пример приложения демонстрирует этот подход с помощью EventBus Greenrobot, и этот пример приложения демонстрирует этот подход с LocalBroadcastManager.

Существуют и другие решения, в которых не задействована истинная шина событий, например служба обновления хранилища, которая обновляет компоненты пользовательского интерфейса с помощью реактивных средств (например, RxJava ведет к LiveData). Однако служба не должна пытаться напрямую манипулировать пользовательским интерфейсом активности, отчасти потому, что там может не быть активности.

...