BroadcastReceiver với nhiều bộ lọc hay nhiều BroadcastReceiver?


115

Tôi có Hoạt động trên Android cần bắt hai chương trình phát sóng khác nhau. Cách tiếp cận hiện tại của tôi là có một chương trình duy nhất BroadcastReceivertrong Activity và bắt cả hai chương trình phát sóng với nó:

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

Tôi chỉ muốn thực thi refresh()nếu Hoạt động của tôi hiển thị trên màn hình, nhưng tôi muốn bắt INTENT_UPDATEvà thực thi update()trong toàn bộ thời gian tồn tại của Hoạt động, bất kể Hoạt động có hiển thị hay không.

Tôi không tìm thấy bất kỳ cách nào để hủy đăng ký chỉ một trong hai bộ lọc mà tôi đăng ký onCreate, vì vậy tôi sử dụng cờ để bật hoặc tắt tác vụ sẽ được thực thi khi INTENT_REFRESHchương trình phát sóng bị bắt, tùy thuộc vào trạng thái của Hoạt động.

Câu hỏi đặt ra là : đây có phải là cách tiếp cận chính xác?

Hoặc, sẽ tốt hơn nếu có hai BroadcastReceiver riêng biệt như sau:

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

Và cái nào có hiệu suất tốt hơn?

Câu trả lời:


210

thay vào đó, bạn có thể cung cấp hai bộ lọc ý định khác nhau:

bộ lọc chỉ để làm mới

IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);

lọc để làm mới và cập nhật

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

bây giờ bạn có thể chuyển đổi giữa các bộ lọc ý định bằng cách đăng ký và hủy đăng ký bộ lọc mong muốn nhưng việc triển khai bộ thu của bạn sẽ giống nhau


@Waqas Bạn có thể cung cấp một ví dụ triển khai BroadcastReceiver sẽ nhận được nhiều ý định không? Nó chỉ là một câu lệnh if-then-else lớn?
gonzobrains

2
@gonzobrains vâng, đối với nhiều ý định, bạn cần sử dụng số lượng câu lệnh if-else bằng nhau để lọc chúng ra
waqaslam

@Waqas Có cách nào để thực hiện điều này động để bạn có một bộ thu phát sóng chung và có thể thêm nhiều bộ xử lý vào nó để không phải sửa đổi khung cơ bản mỗi khi bạn thêm một ý định mới vào nó không?
gonzobrains

chính xác thì ý bạn là gì khi nói "làm điều này một cách linh hoạt" ? Chỉ cần bao gồm tất cả các chuỗi hành động bên trong bộ lọc ý định của bạn và thực hiện if-else để xác định các chuỗi hành động bắt buộc của bạn.
waqaslam

3
Tôi không hiểu tất cả các phiếu ủng hộ cho câu trả lời này. Đối với những gì op đang cố gắng thực hiện, có vẻ như 1 bộ lọc ý định với 2 hành động là đủ. Mã trong khối mã đầu tiên trong câu hỏi dường như là tất cả những gì cần thiết.
hBrent

28

Đối với mọi hành động, hãy tạo IntentFilter và đăng ký nó.

@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
Tôi có nên lo lắng khi gọi registerReceivernhiều lần và chỉ gọi unregisterReceivermột lần không?
mr5

3
Nếu bạn gọi registerReceiver nhiều lần và hủy đăng kýReceiver chỉ một lần thì phiên bản trước của receiver có thể bị rò rỉ. Vì vậy, trường hợp u đăng ký sau đó sử dụng trường hợp đó để hủy đăng ký.
Pawan Yadav

2
Nếu bạn đã đăng ký nhiều lần cho cùng một hành động, thì tôi nói rằng bạn nên lo lắng.
stdout

1
Điều này có nên nản lòng không? Sẽ rất hữu ích cho các nhà phát triển của Google nếu bạn đưa ra một ngoại lệ khi bạn đăng ký cùng một BroadcastReceiver nhiều lần. Thay vào đó, chúng ta nên thêm nhiều hành động vào bộ lọc ý định.
TheRealChx101
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.