Birden çok filtre veya birden fazla BroadcastReceiver içeren BroadcastReceiver?


115

İki farklı yayını yakalaması gereken bir Android Etkinliğim var. Şu anki yaklaşımım, BroadcastReceiverAktivite içinde bir single bulundurmak ve her iki yayını da onunla yakalamak:

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

Ben yürütmek istiyorum refresh()benim Etkinlik ekranda görünür ise sadece ama yakalamak istiyor INTENT_UPDATEve yürütmek update()bakılmaksızın Aktivite görünür olup olmadığına bakılmaksızın, Faaliyet tüm ömrü boyunca.

Kaydolduğum iki filtreden yalnızca birinin kaydını silmenin bir yolunu bulamadım onCreate, bu nedenle INTENT_REFRESH, Aktivite durumuna bağlı olarak yayın yakalandığında yürütülecek eylemi etkinleştirmek veya devre dışı bırakmak için bir bayrak kullanıyorum .

Soru şu : bu doğru yaklaşım mı?

Veya aşağıdaki gibi iki ayrı BroadcastReceiver'a sahip olmak daha mı iyi olur:

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

Ve hangisinin performansı daha iyi?

Yanıtlar:


210

bunun yerine, iki farklı amaç filtresi sağlayabilirsiniz:

sadece yenileme için filtre uygula

IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);

yenileme ve güncelleme için filtre

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

şimdi istediğinizi kaydedip kaydını silerek amaç filtreleri arasında geçiş yapabilirsiniz, ancak alıcınızın uygulaması aynı olacaktır


@Waqas BroadcastReceiver'ın birden çok amacı alacak örnek bir uygulamasını sağlayabilir misiniz? Bu sadece büyük bir eğer-öyleyse-değilse ifadesi mi?
gonzobrains

2
@gonzobrains evet, birden fazla amaç için onları filtrelemek için eşit sayıda if-else ifadesi kullanmanız gerekir
waqaslam

@Waqas Bunu dinamik olarak yapmanın bir yolu var mı, böylece genel bir yayın alıcınız var mı ve ona her yeni amaç eklediğinizde temel çerçeveyi değiştirmek zorunda kalmamak için ona birden çok işleyici ekleyebiliyor musunuz?
gonzobrains

"Bunu dinamik olarak yapmak" ile tam olarak neyi kastediyorsunuz ? Tüm eylem dizelerini niyet filtrelerinize dahil edin ve gerekli eylem dizelerinizi belirlemek için eğer değilse gerçekleştirin.
waqaslam

3
Bu cevaba verilen tüm olumlu oyları anlamıyorum. Operasyonun yapmaya çalıştığı şey için, 2 eylemli 1 niyet filtresi yeterli görünüyor. Sorudaki ilk kod bloğundaki kod, gereken tek şey gibi görünüyor.
hBrent

28

Her eylem için IntentFilter oluşturun ve kaydedin.

@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
registerReceiverBirden çok kez aramaktan ve unregisterReceiveryalnızca bir kez aramaktan endişelenmemeli miyim ?
mr5

3
RegisterReceiver'ı birden çok kez çağırırsanız ve unregisterReceiver'ı yalnızca bir kez çağırırsanız, alıcının önceki örneği sızabilir. Böylece, u örneği kaydedilir ve bu örneği kayıt silme için kullanır.
Pawan Yadav

2
Aynı eyleme birden çok kez kaydolursanız, endişelenmeniz gerektiğini söyleyebilirim.
stdout

1
Bu cesaret kırılmamalı mı? Aynı BroadcastReceiver'ı birden fazla kaydettiğinizde Google geliştiricilerinin bir istisna atması faydalı olacaktır. Bunun yerine, amaç filtresine birden çok eylem eklemeliyiz.
TheRealChx101
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.