5

使用 Android LiveData我希望能够在和回调中取消注册和注册许多BroadcastReceivers 。所以我想做这样的事情:onInactive()onActive()

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

我在想这可能是一种设计模式来清理代码而不是在onDestroy. 您对以这种方式使用 LiveData 有何看法?这里有一个使用它的例子

4

1 回答 1

6

我认为对于接收者,您应该实施LifecycleObserver. 根据LiveDataGoogle codelab的文档,

注意:在 ViewModel 中存储对 Context 或 View 的引用可能会导致内存泄漏。避免引用 Context 或 View 类的实例的字段。onCleared() 方法可用于取消订阅或清除对具有较长生命周期的其他对象的引用,但不适用于清除对 Context 或 View 对象的引用。

因此,您不应该在 LiveData 中进行上下文密集型操作。

相反,以下面的实现为例,

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) {

        }
    }
}

谢谢。

于 2017-06-09T05:12:38.343 回答