This question提出了一个有趣的问题。
OP有一个显示地图的应用程序,此地图需要使用通过短信接收的位置标记进行更新。个别步骤非常简单:可以通过BroadcastReceiver
接收短信,标记可以ItemizedOverlay
显示在MapView
之上。棘手的部分是让接收部分与应用程序的主要部分进行通信。
如果应用具有有效MapActivity
会发生什么情况,然后调用其BroadcastReceiver
作为对传入短信的响应?在MapActivity
代码在同一进程中执行时,BroadcastReceiver
是否被暂停?如果是这样,BroadcastReceiver
通过静态引用(由活动的MapActivity
方法设置?)访问onCreate
是否安全?
相反,应用程序的BroadcastReceiver
是在一个单独的进程中执行的,因此需要其他方式与应用程序的活动进行通信?
答案 0 :(得分: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 Intent。虽然后者持续存在,但第一个更新地图,我只是猜测我会尝试什么。
答案 1 :(得分:1)
BroadcastReceiver
应该在同一个进程中运行。 BroadcastReceiver
旨在昙花一现。因此,它可以执行而不必担心暂停前台Activity
。假设您检查了尚未创建Activity
的情况,您可以通过静态引用直接访问Activity
。但是,通过Intents进行通信可能更有意义。
答案 2 :(得分:0)
正如其他人所指出的,最佳方法似乎是创建一个对应用程序来说是私有的单独意图。活动不是在清单中声明它,而是在活动时注册它。 This answer解释了如何做到这一点。
public BroadcastReceiver
(在清单中声明并处理android.provider.Telephony.SMS_RECEIVED
)应该调用此特定于应用程序的意图。