【问题标题】:Android Architecture component LiveData - how to bind broadcastReceivers to lifecycleAndroid架构组件LiveData - 如何将broadcastReceivers绑定到生命周期
【发布时间】:2017-12-24 19:50:54
【问题描述】:

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

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 有何看法?有一个使用的例子here

【问题讨论】:

    标签: android android-architecture-components android-livedata


    【解决方案1】:

    我认为对于接收者,你应该实现LifecycleObserver。 根据来自 Google codelabLiveData 文档,

    注意:在 ViewModel 中存储对 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) {
    
            }
        }
    }
    

    谢谢。

    【讨论】:

    • 所以你写的是内存泄漏,因为活动上下文永远不会被正确释放
    • @j2emanue:通过application context 不,activity 上下文!
    • @ j2emanue :参考答案中提到的 codelab。它附加了位置侦听器。相反,您可以使用广播接收器!
    • @AndiGeeky 所以.. 如果您在这里也有对 Context 的引用,那么这比问题中的代码好多少?我的意思是,他也可以在那里传递应用程序上下文(使用他的代码和扩展 livedata)。有什么区别?
    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多