Более эффективный способ обновления пользовательского интерфейса от службы, чем намерения?

В настоящее время у меня есть Служба на Android, которая является образцом клиента VOIP, поэтому он прослушивает сообщения SIP, и если он ее получает, запускается экран Activity с компонентами пользовательского интерфейса.

Затем следующие сообщения SIP определяют, что должно отображаться на экране. Например, если в его входящем вызове появится ответ «Ответ» или «Отклонить» или исходящий вызов, он отобразит экран набора номера.

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

Примером может служить следующее:


Intent i = new Intent(); i.setAction(SIPEngine.SIP_TRYING_INTENT); i.putExtra("com.net.INCOMING", true); sendBroadcast(i); Intent x = new Intent(); x.setAction(CallManager.SIP_INCOMING_CALL_INTENT); sendBroadcast(x); Log.d("INTENT SENT", "INTENT SENT INCOMING CALL AFTER PROCESSINVITE"); 

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

Пример кода:


  SipCallListener = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(SIPEngine.SIP_RINGING_INTENT.equals(action)){ Log.d("cda ", "Got RINGING action SIPENGINE"); ringingSetup(); } if(CallManager.SIP_INCOMING_CALL_INTENT.equals(action)){ Log.d("cda ", "Got PHONE RINGING action"); incomingCallSetup(); } } }; IntentFilter filter = new IntentFilter(CallManager.SIP_INCOMING_CALL_INTENT); filter.addAction(CallManager.SIP_RINGING_CALL_INTENT); registerReceiver(SipCallListener, filter); 

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

Поэтому мне было интересно, есть ли другой более эффективный и чистый способ сделать это?

Есть ли способ поддерживать Intents вещание только внутри приложения?

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

ОБНОВЛЕНИЕ 2015:

Этот вопрос / ответ по-прежнему получает немного активности, но это более 5 лет, и все изменилось совсем немного. 5 лет назад, ниже был ответ, как бы я справился с этим. Позже я написал очень легкое решение для инъекций зависимостей, которое я использовал некоторое время (что я упомянул в комментариях). В настоящее время я бы ответил на этот вопрос, используя Dagger и RxAndroid. Кинжал, чтобы ввести class «посредника» и в Службу, и во все действия, которые необходимо уведомить, Служба переместит обновление состояния в class посредника, а class посредника будет подвергать наблюдаемые действия для использования обновления статуса ( вместо приемника вещания OP).

Оригинальный ответ

Я обычно подclassу приложения и позволяю моей связи в приложении проходить через этот class (или иметь посредника, принадлежащего Приложению, выполнять работу … независимо от того, что приложение является точкой входа для связи службы). У меня есть связанная служба, которая также нуждается в обновлении интерфейса (гораздо проще, чем ваша, но та же идея), и в основном он сообщает приложению о своем новом состоянии, и приложение может затем передать эту информацию так или иначе в активная деятельность. Вы также можете сохранить указатель на текущую активную деятельность (если ее несколько) и принять решение о том, нужно ли просто обновлять текущую деятельность, транслировать намерение запуска другого действия, игнорировать сообщение и т. Д. Я бы также подclass Activity и ваш новый базовый class активности скажите Приложению, что он в настоящее время является активным в onResume и что он приостанавливается в onPause (для случаев, когда ваша служба работает в фоновом режиме и все действия приостановлены).

РЕДАКТИРОВАТЬ:

В ответ на комментарий, здесь более подробно.

В настоящее время ваше приложение состоит из classов, производных от производных и служб, по большей части. По сути, вы получаете функциональность из экземпляра classа android.app.Application. Это объявлено в вашем манифесте (по умолчанию) со следующей строкой:

  

Элемент приложения в манифесте не использует атрибут android: name, поэтому он просто создает экземпляр classа android.app.Application по умолчанию для представления вашего глобального контекста приложения.

В моих приложениях я создаю подclass приложения (ApplicationEx, например), и я расскажу в своем приложении через манифест, что это class для создания экземпляра в качестве глобального контекста приложения. Например:

  

Теперь я могу добавлять методы в ApplicationEx для действий и сервисов для связи. Всегда есть один экземпляр вашего глобального контекста приложения, так что это ваша отправная точка, если что-то должно быть глобальным для вашего приложения.

Вторая часть этого заключается в том, что вместо того, чтобы получать мои сервисы и действия из Сервиса и Activity, я создаю подclass каждого из них с методом getAppContext, который возвращает возвращаемое значение getApplicationContext (которое существует уже в обоих этих classах, потому что они происходят из контекста ) к моему classу ApplicationEx.

Так……..

Все сказанное добавляет свойство CurrentActivity к classу ApplicationEx типа Activity (или ActivityBase, если вы подclassифицируете его так же, как и я). В методе onResume ActivityBase вы переходите к ApplicationEx для его установки CurrentActivity для этой активности. Теперь вы можете выставить методы на ApplicationEx для передачи информации непосредственно в текущую деятельность вместо того, чтобы полагаться на механизмы Intent.

Это примерно так же ясно, как я могу это сделать

Вы можете отправлять трансляции непосредственно к своему собственному приложению, а не к системе с помощью LocalBroadcastManager :

Помощник для регистрации и отправки трансляций намерений на локальные объекты в рамках вашего процесса. Это имеет ряд преимуществ перед отправкой глобальных передач с помощью sendBroadcast (Intent):

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

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

Это более эффективно, чем отправка глобальной трансляции через систему.

Тем не менее, я по-прежнему рекомендую использовать подход «Служба» и локально привязывать и говорить через обработчика, когда это необходимо, для обновления компонентов пользовательского интерфейса.

  • Лучший способ переключения между UISplitViewController и другими controllerами представлений?
  • Как я могу складывать / накладывать jPanels в Java?
  • Как получить доступ к переменным из разных classов в tkinter?
  • Как совместить прослушиватели событий с запросом на событие?
  • JTable Right Align Header
  • Какова связь между ContentPane и JPanel?
  • Как работает stream отправки событий?
  • Мероприятия по событиям в саперах
  • Настройка цвета фона элемента макета Android
  • Безопасно ли создавать виджеты Swing / AWT NOT на тему Dispatch Event?
  • Что такое MVP и MVC и в чем разница?
  • Interesting Posts

    Технические причины форматирования при увеличении на 1 в цикле «for»?

    Неизменяемые объекты являются streamобезопасными, но почему?

    Рисованное изображение на canvasе

    Инструменты для поиска узких мест в конфигурации оборудования

    Инъекция зависимостей через конструкторы или средства определения свойств?

    Ошибка: Достигнуто 10 $ digest () итераций. Aborting! с динамическим сортировочным предикатом

    Log4j Предупреждение при инициализации?

    Графическая карта, не работающая в Windows 8.1 на Mac

    Preincrement быстрее, чем постинкремент в C ++ – правда? Если да, то почему?

    Что означает typedef с круглыми скобками типа «typedef int (f) (void)»? Это прототип функции?

    Используйте обе таблицы учетных записей и пользователей с помощью программы «Разработка»

    Ошибка: java.util.zip.ZipException: дублировать запись

    Как Windows вычисляет процент фрагментации?

    Как сервер может выполнить сеанс с клиентом в RMI

    Ограничение таблицы SQLite – уникальное по нескольким столбцам

    Давайте будем гением компьютера.