【问题标题】:BroadcastReceiver with multiple filters or multiple BroadcastReceivers?具有多个过滤器或多个广播接收器的广播接收器?
【发布时间】:2012-02-26 00:55:33
【问题描述】:

我有一个需要捕获两个不同广播的 Android 活动。我目前的方法是在 Activity 中有一个 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();
            }
        }
    }
}

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

我没有找到任何方法来仅取消注册我在onCreate 中注册的两个过滤器之一,因此我使用一个标志来启用或禁用在捕获INTENT_REFRESH 广播时要执行的操作,具体取决于关于 Activity 的状态。

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

或者,最好有两个单独的广播接收器,如下所示:

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

哪一个性能更好?

【问题讨论】:

    标签: android android-intent broadcastreceiver


    【解决方案1】:

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

    只过滤刷新

    IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
    

    过滤刷新和更新

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

    现在您可以通过注册和取消注册所需的过滤器来在意图过滤器之间切换,但您的接收器的实现将是相同的

    【讨论】:

    • @Waqas 你能提供一个接收多个意图的广播接收器的示例实现吗?这只是一个大的 if-then-else 语句吗?
    • @gonzobrains 是的,对于多个意图,您需要使用相同数量的 if-else 语句将它们过滤掉
    • @Waqas 有没有办法动态执行此操作,以便您拥有通用广播接收器并可以向其添加多个处理程序,以便每次添加新意图时都不必修改基本框架给它?
    • “动态执行此操作” 到底是什么意思?只需在您的意图过滤器中包含所有操作字符串并执行 if-else 来识别您所需的操作字符串。
    • 我不明白这个答案的所有赞成票。对于 op 试图做的事情,似乎 1 个具有 2 个动作的意图过滤器就足够了。问题中第一个代码块中的代码似乎就是所有需要的。
    【解决方案2】:

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

    【讨论】:

    • 我不应该担心多次调用registerReceiver而只调用一次unregisterReceiver吗?
    • 如果你多次调用 registerReceiver 而只调用 unregisterReceiver 一次,那么之前的接收器实例可能会泄漏。因此,您注册的实例然后使用该实例进行注销。
    • 如果您要在同一个操作中多次注册,那么我会说您应该担心。
    • 不应该劝阻吗?当您多次注册同一个 BroadcastReceiver 时,Google 开发人员抛出异常会很有帮助。相反,我们应该向意图过滤器添加多个操作。
    【解决方案3】:

    使用 KOTLIN 可以内联:

      broadcastReceiver = NukeBroadcastReceiver()
            registerReceiver(broadcastReceiver, IntentFilter().apply {
                addAction(ACTION_DESTROY_EVERYTHING)
                addAction(ACTION_RESTART_WORLD)
            })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多