从广播接收器更新活动

3

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

OP有一个显示地图的应用程序,这张地图需要通过短信消息接收到的位置标记进行更新。各个步骤都相当简单:短信消息可以通过BroadcastReceiver接收,标记可以通过ItemizedOverlayMapView上方显示。棘手的部分是使接收部分与应用程序的主要部分通信。

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

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

3个回答

4

阅读文档,看起来广播接收器在不同的进程中执行,但我不能百分之百确定( BroadcastReceiver 生命周期)

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

话虽如此,我认为从onReceive访问Activity并不安全,因为它是一个不同的进程,很可能会崩溃。

请注意,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 应始终通过 Service 持久化新标记(永不在 onReceive 内部),并且应通知潜在的活动 MapActivity 已添加新标记,如果它处于活动状态,则会监听。或者,更简单的是,Activity 和 BroadcastReceiver 监听相同的 SMS Intent。虽然后者持久化它,但前者更新地图,我只是猜测我会尝试什么。

1

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


0
作为其他人指出的最佳方法,似乎是创建一个专门为应用程序私有的意图。在清单中声明它的代替方法是,在活动处于活动状态时注册它。此答案解释了如何实现这一点。
然后,公共的BroadcastReceiver(在清单中声明并处理android.provider.Telephony.SMS_RECEIVED)应调用这个特定于应用程序的意图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接