BroadcastReceiver有多个过滤器或多个BroadcastReceivers?

Lor*_*ori 107 android broadcastreceiver android-intent

我有一个需要捕获两个不同广播的Android活动.我目前的方法是BroadcastReceiver在Activity中使用一个单独的方法来捕获广播:

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想refresh()只在屏幕上显示我的Activity时执行,但我想在Activity的整个生命周期内捕获INTENT_UPDATE并执行update(),无论Activity是否可见.

我没有找到任何方法只注销我注册的两个过滤器中的一个onCreate,所以我使用一个标志来启用或禁用INTENT_REFRESH捕获广播时要执行的操作,具体取决于活动的状态.

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

或者,最好有两个单独的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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

哪一个有更好的表现?

waq*_*lam 193

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

过滤器仅用于刷新

IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
Run Code Online (Sandbox Code Playgroud)

过滤器用于刷新和更新

IntentFilter filterRefreshUpdate = new IntentFilter();
filterRefreshUpdate.addAction(Params.INTENT_REFRESH);
filterRefreshUpdate.addAction(Params.INTENT_UPDATE);
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过注册和取消注册所需的过滤器来切换目标过滤器,但您的接收器的实现方式是相同的

  • 我不明白这个答案的所有支持者.对于op试图做的事情,似乎1个具有2个动作的意图过滤器就足够了.问题中第一个代码块中的代码似乎就是所需要的. (3认同)
  • @gonzobrains是的,对于多个意图,您需要使用相同数量的if-else语句来过滤掉它们 (2认同)

Paw*_*dav 27

对于每个操作,创建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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 我不应该担心多次调用`registerReceiver`并且只调用一次`unregisterReceiver`吗? (4认同)
  • 如果你多次调用registerReceiver并且只注册一次unregisterReceiver,那么之前的接收器实例可能会泄漏.因此,实例u注册然后使用该实例进行取消注册. (3认同)
  • 如果你在同一个动作上多次注册,那么我会说你应该担心. (2认同)

Hit*_*ahu 12

使用 KOTLIN 您可以内联完成:

  broadcastReceiver = NukeBroadcastReceiver()
        registerReceiver(broadcastReceiver, IntentFilter().apply {
            addAction(ACTION_DESTROY_EVERYTHING)
            addAction(ACTION_RESTART_WORLD)
        })
Run Code Online (Sandbox Code Playgroud)