具有多个过滤器或多个BroadcastReceiver的BroadcastReceiver?


115

我有一个Android活动,需要捕捉两个不同的广播。我当前的方法是BroadcastReceiver在活动中包含一个广播,并同时捕获两个广播:

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()

我没有找到任何方法来仅注销我在其中注册的两个过滤器之一onCreate,因此我会INTENT_REFRESH根据活动的状态使用一个标志来启用或禁用捕获广播时要执行的操作。

问题是:这是正确的方法吗?

或者,最好有两个单独的BroadcastReceiver,如下所示:

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();
            }
        }
    }
}

哪一个性能更好?

Answers:


210

相反,您可以提供两个不同的意图过滤器:

过滤器仅刷新

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陈述吗?
gonzobrains

2
@gonzobrains是的,对于多个意图,您需要使用相等数量的if-else语句将其过滤掉
waqaslam

@Waqas是否可以动态地执行此操作,以使您拥有通用的广播接收器,并可以向其中添加多个处理程序,从而不必在每次向其添加新的意图时都修改基本框架?
gonzobrains

“动态地做到这一点”到底是什么意思?只需将所有操作字符串包含在意图过滤器中,然后执行if-else即可识别所需的操作字符串。
waqaslam

3
我不了解此答案的所有支持。对于op试图做的事情,似乎1个意图过滤器和2个动作就足够了。问题中第一个代码块中的代码似乎就是所需要的。
hBrent

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

3
如果u多次调用registerReceiver且仅一次取消unregisterReceiver,则先前的接收器实例可能会泄漏。因此,您注册的实例然后使用该实例取消注册。
Pawan Yadav

2
如果您要在同一操作上多次注册,那么我想您应该担心。
标准输出

1
不应该这样吗?当您多次注册同一个BroadcastReceiver时,Google开发人员抛出异常会很有帮助。相反,我们应该向意图过滤器添加多个操作。
TheRealChx101 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.