3

この質問は興味深い問題を提起しました。

OP には地図を表示するアプリがあり、この地図は SMS メッセージで受信した位置マーカーで更新する必要があります。個々の手順は非常に簡単です。SMS メッセージは で受信できBroadcastReceiver、マーカーは でItemizedOverlay上に表示できますMapView。注意が必要な部分は、受信部分がアプリのメイン部分と通信することです。

  • アプリにアクティブなMapActivityがありBroadcastReceiver、着信 SMS への応答として呼び出された場合はどうなりますか? コードが同じプロセスで実行されている間、MapActivity中断されていますか? もしそうなら、 (アクティビティのメソッドによって設定される)静的参照を介してアクセスするのはBroadcastReceiver安全ですか?BroadcastReceiverMapActivityonCreate

  • 逆に、アプリBroadcastReceiverは別のプロセスで実行されるので、アプリのアクティビティと通信するには別の方法が必要ですか?

4

3 に答える 3

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 は常に新しいマーカーを永続化する必要があり (Service を介してonReceive内では決して行わないでください)、アクティブである可能性がある MapActivity に、新しいマーカーが追加されたことを通知する必要があります。

または、さらに簡単に、Activity と BroadcastReceiver が同じ SMS Intent をリッスンします。後者はそれを維持しますが、最初はマップを更新しますが、私が何をしようとしているのかを推測しています。

于 2012-04-18T21:24:16.413 に答える
1

BroadcastReceiver同じプロセスで実行する必要があります。BroadcastReceiver短命になるように設計されています。そのため、フォアグラウンドの中断について実際に心配することなく実行できますActivity。がまだ作成されていないActivity場合をチェックしたと仮定すると、静的参照を介して直接アクセスできる可能性があります。Activityただし、インテントを介して通信する方が理にかなっている場合があります。

于 2012-04-18T21:11:15.933 に答える
0

他の人が指摘したように、最良のアプローチは、アプリ専用の別の意図を作成することのようです。マニフェストで宣言する代わりに、アクティビティはアクティブになるたびにそれを登録します。この回答は、これの方法を説明しています。

パブリックBroadcastReceiver(マニフェストで宣言され、 を処理するandroid.provider.Telephony.SMS_RECEIVED) は、このアプリケーション固有のインテントを呼び出す必要があります。

于 2012-04-18T21:20:27.520 に答える