Search code examples
androidandroid-architecture-componentsandroid-livedata

Android Architecture component LiveData - how to bind broadcastReceivers to lifecycle


Using Android LiveData I'd like to be able to unregister and register many BroadcastReceivers in the onInactive() and onActive() call backs. So I want to do something like this:

public class BroadcastRecieverLiveData extends LiveData<BroadCastReciever> {
    private BroadcastReciever reciever;
    private Context context;

    public BroadcastRecieverLiveData(Context context) {
        this.context = context;
    }

    @Override
    protected void onActive() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("SOME_ACTION");
        filter.addAction("SOME_OTHER_ACTION");

        reciever = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //do something based on the intent's action
            }
        };
        registerReceiver(reciever, filter);
    }

    @Override
    protected void onInactive() {
        if (reciever != null) {
            context.unregisterReceiver(reciever);
        }
    }
}

I was thinking this could be a design pattern to be clean up of code instead of relaying on onDestroy. What are your thoughts on using LiveData this way? There is an example of using it here


Solution

  • I think for receivers, you should implement LifecycleObserver. As per LiveData documentation from Google codelab,

    Caution: Storing a reference to a Context or View in a ViewModel can result in memory leaks. Avoid fields that reference instances of the Context or View classes. The onCleared() method is useful to unsubscribe or clear references to other objects with a longer lifecycle, but not for clearing references to Context or View objects.

    So, You should not do context intensive operation in LiveData.

    Instead, take an example of below implementation,

    import android.arch.lifecycle.Lifecycle;
    import android.arch.lifecycle.LifecycleObserver;
    import android.arch.lifecycle.LifecycleOwner;
    import android.arch.lifecycle.OnLifecycleEvent;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    
    public class ReceiverManager implements LifecycleObserver {
    
        private final Context mContext;
        private final MyBrodacastReceiver myBrodacastReceiver;
    
        public ReceiverManager(LifecycleOwner lifecycleOwner,
                               Context context) {
            mContext = context;
            myBrodacastReceiver = new MyBrodacastReceiver();
            lifecycleOwner.getLifecycle().addObserver(this);
    
        }
    
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        void registerYourReceiver() {
            mContext.registerReceiver(myBrodacastReceiver, new IntentFilter());
        }
    
    
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        void unRegisterYourReceiver() {
            mContext.unregisterReceiver(myBrodacastReceiver);
        }
    
        private static class MyBrodacastReceiver extends BroadcastReceiver {
    
            @Override
            public void onReceive(Context context, Intent intent) {
    
            }
        }
    }
    

    Thanks.