2012-04-18 4 views
3

This question возник интересный вопрос.Обновление деятельности от BroadcastReceiver

У OP есть приложение, которое отображает карту, и эта карта должна быть обновлена ​​с помощью маркеров местоположения, которые принимаются через SMS-сообщения. Отдельные шаги довольно просты: SMS-сообщения могут быть получены с помощью BroadcastReceiver, маркеры могут отображаться на ItemizedOverlay поверх MapView. Трудная часть заключается в том, чтобы принимающая часть общалась с основной частью приложения.

  • Что произойдет, если приложение имеет активное MapActivity, а затем его BroadcastReceiver вызывается в ответ на входящее SMS? Подвешен ли MapActivity код BroadcastReceiver в том же процессе? Если да, то это безопасно для BroadcastReceiver, чтобы получить доступ к MapActivity через статические ссылки (который устанавливается onCreate методы активности в?

  • С другой стороны, это BroadcastReceiver выполняется в отдельном процессе, и, следовательно, потребуется какой-либо другой способ приложения, в общаться с activty в приложении?

ответ

4

Чтение документации, это выглядит как BroadcastReceiver выполняется на другом процессе, Тхо я не уверен на 100% (BroadcastReceiver lifecycle)

Процесс, который в настоящее время выполнения BroadcastReceiver (то есть, в настоящее время работает код в методе onReceive (Context, Intent)) рассматривается как основной процесс.

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

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

public void onResume(){ 
    activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
    [...] 
    } 

    public void onPause() { 
    [...] 
    activity.unregisterReceiver(powerStatusReceiver); 
    } 

И вы определяете BroadcastReceiver как частный класс внутри общественного класса

final class InactivityTimer { 

[onResume, onPause, rest of the stuff ...] 

    private final class PowerStatusReceiver extends BroadcastReceiver { 
     @Override 
     public void onReceive(Context context, Intent intent){ 
      if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { 
      // 0 indicates that we're on battery 
      // In Android 2.0+, use BatteryManager.EXTRA_PLUGGED 
      int batteryPlugged = intent.getIntExtra("plugged", -1); 
      if (batteryPlugged > 0) { 
       InactivityTimer.this.cancel(); 
      } 
      } 
     } 
     } 
} 

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

Или, что еще проще, Activity и BroadcastReceiver прослушивают одно и то же SMS-намерение. Пока последний упорствует, первый обновляет карту, а я просто догадываюсь, что я попробую.

1

BroadcastReceiver должны работать в том же процессе. BroadcastReceiver предназначены для недолгих. Как таковых, он может выполняться без какого-либо реального беспокойства о приостановлении переднего плана Activity. Вы могли бы потенциально получить доступ к Activity напрямую через sta tic, предполагая, что вы проверили случай, когда Activity еще не создан. Однако может быть больше смысла общаться через Intents.

0

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

Публикация BroadcastReceiver (объявленная в манифесте и обрабатывающая android.provider.Telephony.SMS_RECEIVED) должна затем ссылаться на это намерение конкретного приложения.

Смежные вопросы