在 Viewmodel 中访问 BroadCastReceiver

我正在努力选择正确的方式将数据从 broadcastReceiver 传递到 ViewModel,然后从那里将数据传递到我的存储库并更新 LiveData。我使用FCM推送通知,并有本地的broadCastReceiver,它使用ActiveLifecycle。

我发现从 BroadcastReceiver 访问 ViewModel 是一种不好的做法,但不知道为什么?

如果我管理广播接收器的生命周期,它应该不会引起任何问题...那么,将收到的数据从FCM传递到我的存储库的中介LiveData的最佳方法是什么?我使用MediatorLiveData,因为我添加了不同的LiveData源(API请求和FCM)。

非常感谢您的建议和实施broadCastReceiver的正确方法。

我考虑过从BroadCastReceiver访问存储库,如下所示:

RepositoryMain.getSingletonInstance().setResponse(state);

答案 1

您需要定义单一事实来源SSoT)。在你的情况下,它(如果封装数据库持久性存储,SSoT它是数据库)。现在,您需要通过 SSoT () 实现从接收器到视图的数据流,如下面的示例所示:RepositoryRepositoryRepository

接收器实现

public class FcmReceiver extends BroadcastReceiver {

    private final MutableLiveData<MyData> mData = new MutableLiveData<>();

    public LiveData<MyData> getData() {
        return mData;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // entry point of data
        mData.setValue(new MyData());
    }
}

存储 库

public class Repository {

    private static final Repository INSTANCE = new Repository();

    private final MediatorLiveData<MyData> mData = new MediatorLiveData<>();

    private Repository() {}

    public static Repository instance() {
        return INSTANCE;
    }

    public LiveData<MyData> getData() {
        return mData;
    }

    public void addDataSource(LiveData<MyData> data) {
        mData.addSource(data, mData::setValue);
    }

    public void removeDataSource(LiveData<MyData> data) {
        mData.removeSource(data);
    }
}

查看模型

public class MyViewModel extends ViewModel {

    public LiveData<MyData> getData() {
        // for simplicity return data directly to view
        return Repository.instance().getData();
    }
}

活动

接收器数据绑定,并且Repository

public class MainActivity extends AppCompatActivity {

    private FcmReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReceiver = new FcmReceiver();
    }

    @Override
    protected void onStart() {
        super.onStart();
        // add data source
        Repository.instance().addDataSource(mReceiver.getData());
        registerReceiver(mReceiver, IntentFilter.create("action", "type"));
    }

    @Override
    protected void onStop() {
        super.onStop();
        // don't forget to remove receiver data source
        Repository.instance().removeDataSource(mReceiver.getData());
        unregisterReceiver(mReceiver);
    }
}

答案 2

我认为您不需要在视图模型中访问BroadCastReceiver。或者,使用 BroadCastReceiver 在活动之间移动数据,如果要对数据执行任何逻辑,请将其发送到与该活动相关的 viewModel。

简单来说:假设我们有以下组件:
ActivityOne 观察 ViewModelOne
ActivityTwo 观察 ViewModelTwo
BroadCastReceiver [从 ActivityOne 发送操作]。活动二监听这些操作

一旦ActiveOneviewModelOne接收到数据,它就会通过BroadCastReceiver发送数据。

ActivityTwo已经注册了BroadCastReceiver,因此它接收这些操作,如果它需要对数据做任何逻辑,它可以将其发送到ViewModelTwo


推荐