Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 562
j2emanue Avatar asked May 30 '17 20:05

j2emanue


1 Answers

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.

like image 136
AndiGeeky Avatar answered Nov 14 '22 12:11

AndiGeeky