16

ローカルブロードキャストを使用して、AsyncTaskが動作を終了したことをサービスに通知していますが、小さな問題があります。ブロードキャストは1回だけ送信されます(アプリの起動時にのみ呼び出される関数によって作成されます)が、 2回受け取ります。

簡略化されたコード:

@Override
protected void onPostExecute(HttpResponse result) {
    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getBaseContext());
    localBroadcastManager.sendBroadcast(new Intent(getString(R.string.bc_CONNECTED)));
}

サービス中:

private BroadcastReceiver connectedBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(getString(R.string.app_tag), "broadcast received !!");
    }
};

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LocalBroadcastManager.getInstance(this).registerReceiver(connectedBroadcastReceiver, new IntentFilter(getString(R.string.bc_CONNECTED)));
    return START_STICKY;
}

誰かがそのような奇妙な行動に遭遇したことがありますか?

4

5 に答える 5

26

同じ問題がありました。問題は、onCreateメソッドとonResumeメソッドでレシーバーを登録していたことでした。onCreateから削除すると、問題は解決しました。

于 2013-03-01T18:54:02.913 に答える
12

ブロードキャストに応答する前に、常にインテントアクションを確認する必要があります。

public void onReceive(Context context, Intent intent){
      if(intent.getAction() != null && intent.getAction().equals(getString(R.string.bc_CONNECTED))){
      Log.d(getString(R.string.app_tag), "broadcast received !!");
 }
}

ドキュメントを確認してください。それはあなたが偽の電話を受けるかもしれないと言います。したがって、常にアクションを確認してください

registerReceiver(BroadcastReceiver、IntentFilter)およびアプリケーションマニフェストで使用されるインテントフィルターは、排他的であることが保証されていません。これらは、適切な受信者を見つける方法についてのオペレーティングシステムへのヒントです。送信者は、フィルターの解決をバイパスして、特定の受信者に配信を強制することができます。このため、onReceive()実装は、受信する可能性のある予期しないインテントを無視して、既知のアクションにのみ応答する必要があります。

于 2012-09-16T18:42:17.420 に答える
1

2つのインテントフィルターがあったため、2回登録していたため、この問題が発生しました。そのため、システムは同じインテントを2回通過していました。

  LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver,intentFilterNews);
  LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver,intentFilterWeather);
于 2016-09-08T06:57:01.600 に答える
1

アプリを終了するときにレシーバーの登録を解除しますか?それ以外の場合は、各アプリで別の受信機が登録されます。または、受信者を登録する前に、受信者が以前のアプリ呼び出しですでに登録されているかどうかを確認する必要があります。

于 2017-04-11T13:41:26.637 に答える
1

または(fragmnetの場合)の代わりに、任意のコンポーネント(など)のメソッドに登録BroadcastReceiverしてください。onCreateActivity, Fragment, ServiceonResumeonViewCreated

例えば

val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Log.d("TAGGg",intent?.getBooleanExtra("ext", false).toString())
    }
}

// On Create method of component
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receiver, IntentFilter("test-event"))
}

onStop()また、またはでレシーバーの登録を解除してくださいonDestroy()

LocalBroadcastManager.getInstance(requireActivity()).unregisterReceiver(receiver)
于 2021-07-06T06:42:14.820 に答える