从广播接收器更新活动



这个问题提出了一个有趣的问题。

OP有一个显示地图的应用程序,需要用通过短信接收的位置标记更新此地图。各个步骤相当简单:SMS消息可以由BroadcastReceiver接收,标记可以通过MapView顶部的ItemizedOverlay显示。棘手的部分是让接收部分与应用程序的主要部分进行通信。

  • 如果应用具有活动MapActivity,然后调用其BroadcastReceiver作为对传入短信的响应,会发生什么情况?在同一进程中执行BroadcastReceiver代码时,MapActivity是否挂起?如果是这样,BroadcastReceiver通过静态引用(由活动的onCreate方法设置)访问MapActivity是否安全?

  • 相反,应用的BroadcastReceiver是否在单独的进程中执行,因此需要其他方式与应用的活动进行通信?

阅读文档,看起来 BroadcastReceiver 是在不同的进程中执行的,但我不是 100% 确定(BroadcastReceiver 生命周期)

当前正在执行 BroadcastReceiver 的进程(即当前在其 onReceive(Context, Intent) 方法中运行代码)被视为前台进程

也就是说,我认为从onReceive访问活动是不安全的,因为这是一个不同的过程,它可能会崩溃。

考虑到活动也可以充当广播接收器,您必须控制在其生命周期中何时主动侦听事件。这样,您就可以订阅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 应始终保留新标记(通过服务,而不是在 onTReceive 内部),并且它应该通知潜在活动的 MapActivity 添加了新标记,如果它处于活动状态,它将侦听。

或者,更简单的是,活动和广播接收器侦听相同的 SMS 意图。虽然后者坚持它,但第一个更新地图,我只是猜测我会尝试什么。

BroadcastReceiver应在同一进程中运行。 BroadcastReceiver被设计为短暂的。因此,它可以执行,而无需真正担心挂起前台Activity。假设您检查了尚未创建Activity的情况,则可能会通过静态引用直接访问Activity。但是,通过 Intents 进行通信可能更有意义。

正如其他人指出的那样,最好的方法似乎是创建一个对应用程序私有的单独意图。活动不是在清单中声明它,而是在它处于活动状态时注册它。这个答案解释了如何做到这一点。

然后,公共BroadcastReceiver(在清单中声明并处理android.provider.Telephony.SMS_RECEIVED)应调用此特定于应用程序的意图。

最新更新