3

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

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

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

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

4

3 回答 3

4

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

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

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

考虑到 Activity 也可以充当广播接收器,但您必须控制它在其生命周期中何时主动侦听事件。这样,你就可以订阅 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();
            }
          }
        }
      }
}

So, the BroadcastReceiver should always persist the new markers (through a Service, never inside the onReceive) AND it should notify a potentially active MapActivity that new markers have been added, which will be listening if it's active.

Or, even easier, the Activity and the BroadcastReceiver listen for the same SMS Intent. While the latter persists it, the first updates the map, tho I'm just guessing what I would try.

于 2012-04-18T21:24:16.413 回答
1

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

于 2012-04-18T21:11:15.933 回答
0

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

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

于 2012-04-18T21:20:27.520 回答