複数のフィルターを備えたBroadcastReceiverまたは複数のBroadcastReceivers?


115

2つの異なるブロードキャストをキャッチする必要があるAndroidアクティビティがあります。私の現在のアプローチはBroadcastReceiver、アクティビティ内に1つを持ち、それで両方のブロードキャストをキャッチすることです。

public class MyActivity extends Activity {
    private MyActivity.BroadcastListener mBroadcastListener;
    private boolean mIsActivityPaused = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylayout);

        // Create the broadcast listener and register the filters
        mIsActivityPaused = false;
        mBroadcastListener = new BroadcastListener();

        IntentFilter filter = new IntentFilter();
        filter.addAction(Params.INTENT_REFRESH);
        filter.addAction(Params.INTENT_UPDATE);
        registerReceiver(mBroadcastListener, filter);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mIsActivityPaused = false;
    }

    @Override
    protected void onPause() {
        super.onPause();
        mIsActivityPaused = true;
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(mBroadcastListener);
        super.onDestroy();
    }

    private void refresh() {
        // refresh
    }

    private void update() {
        // update
    }

    private class BroadcastListener extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Params.INTENT_REFRESH && !mIsActivityPaused)) {
                refresh();
            } else if (intent.getAction().equals(Params.INTENT_UPDATE)) {
                update();
            }
        }
    }
}

refresh()アクティビティが画面に表示されている場合にのみ実行したいのですが、アクティビティが表示されているかどうかに関係なく、アクティビティの存続期間全体にわたってキャッチINTENT_UPDATEして実行したいですupdate()

に登録する2つのフィルターのいずれか1つだけを登録解除する方法が見つからなかったため、アクティビティの状態に応じて、onCreateフラグを使用して、INTENT_REFRESHブロードキャストがキャッチされたときに実行されるアクションを有効または無効にします。

問題は、これが正しいアプローチかどうかです。

または、次のように2つの個別のBroadcastReceiversを用意することをお勧めします。

public class MyActivity extends Activity {
    private MyActivity.BroadcastListenerRefresh mBroadcastListenerRefresh;
    private MyActivity.BroadcastListenerUpdate mBroadcastListenerUpdate;
    private boolean mIsBroadcastListenerRefreshRegistered = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create the broadcast listeners
        mBroadcastListenerRefresh = new BroadcastListenerRefresh();
        mBroadcastListenerUpdate = new BroadcastListenerUpdate();

        registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
        registerReceiver(mBroadcastListenerUpdate, new IntentFilter(Params.INTENT_UPDATE));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mBroadcastListenerRefresh != null && !mIsBroadcastListenerRefreshRegistered) {
            registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
            mIsBroadcastListenerRefreshRegistered = true;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mBroadcastListenerRefresh != null && mIsBroadcastListenerRefreshRegistered) {
            unregisterReceiver(mBroadcastListenerRefresh);
            mIsBroadcastListenerRefreshRegistered = false;
        }
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(mBroadcastListenerRefresh);
        unregisterReceiver(mBroadcastListenerUpdate);
        super.onDestroy();
    }

    private void refresh() {
        // refresh
    }

    private void update() {
        // update
    }

    private class BroadcastListenerRefresh extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Params.INTENT_REFRESH)) {
                refresh();
            }
        }
    }

    private class BroadcastListenerUpdate extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Params.INTENT_UPDATE)) {
                update();
            }
        }
    }
}

そして、どれがより良い性能を持っていますか?

回答:


210

代わりに、2つの異なるインテントフィルターを提供できます。

更新のみのフィルター

IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);

更新と更新のフィルター

IntentFilter filterRefreshUpdate = new IntentFilter();
filterRefreshUpdate.addAction(Params.INTENT_REFRESH);
filterRefreshUpdate.addAction(Params.INTENT_UPDATE);

これで、目的のフィルターを登録および登録解除することでインテントフィルターを切り替えることができますが、レシーバーの実装は同じです。


@Waqas複数のインテントを受け取るBroadcastReceiverの実装例を提供できますか?それは単にif-then-elseの大きなステートメントですか?
ゴンゾブレーン

2
@gonzobrainsはい、複数のインテントについては、等しい数のif-elseステートメントを使用してそれらを
除外する

@Waqas新しいブロードキャストインテントを追加するたびに基本フレームワークを変更する必要がないように、汎用ブロードキャストレシーバーを複数のハンドラーに追加できるように、これを動的に行う方法はありますか?
ゴンゾブレイン2013年

「これを動的に行う」とはどういう意味ですか?インテントフィルター内にすべてのアクション文字列を含め、if-elseを実行して必要なアクション文字列を特定するだけです。
waqaslam 2013年

3
この回答に対する賛成票がすべてわかりません。オペレーションがしようとしていたことについては、2つのアクションを持つ1つのインテントフィルターで十分であるようです。問題の最初のコードブロックのコードは、必要なすべてのようです。
hBrent 2017

28

アクションごとに、IntentFilterを作成して登録します。

@Override
protected void onResume() {

    super.onResume();

    BroadcastListener receiver = new BroadcastListener();

    // Register the filter for listening broadcast.
    IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
    IntentFilter filterUpdate = new IntentFilter(Params.INTENT_UPDATE);

    registerReceiver(receiver, filterRefresh);
    registerReceiver(receiver, filterUpdate);
} 



private class BroadcastListener extends BroadcastReceiver {
    public void onReceive(Context ctx, Intent intent) {

        if (intent.getAction().equals(Params.INTENT_UPDATE)) {
            update();
        } else if(intent.getAction().equals(Params.INTENT_REFRESH)) {
            refresh();
        }
    }

}

4
私は呼び出して心配するべきではありませんregisterReceiver複数回と呼び出すunregisterReceiver一度だけ?
mr5 2015

3
registerReceiverを複数回呼び出し、unregisterReceiverを1回だけ呼び出すと、レシーバーの以前のインスタンスがリークする可能性があります。したがって、インスタンスuは登録され、そのインスタンスを使用して登録解除されます。
Pawan Yadav 2015

2
同じアクションで複数回登録する場合は、心配する必要があります。
stdout 2015

1
これはお勧めできませんか?同じBroadcastReceiverを2回以上登録するときに、Google開発者が例外をスローすると便利です。代わりに、インテントフィルターに複数のアクションを追加する必要があります。
TheRealChx101 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.