我正在努力选择将数据从 broadcastReceiver 传递到 ViewModel 的正确方法,然后从那里将数据传递到我的存储库并更新 LiveData。我使用 FCM 推送通知并拥有使用 ActivityLifecycle 的本地 broadCastReceiver。
我发现从 BroadcastReceiver 访问 ViewModel 是不好的做法,但不确定为什么?
如果我管理 broadcastReceiver 的生命周期,它应该不会引起任何问题...那么将接收到的数据从 FCM 传递到我的存储库的 MediatorLiveData 的最佳方法是什么?我使用 MediatorLiveData,因为我添加了不同的实时数据源(API 请求和 FCM)。
非常感谢您提供实现 broadCastReceiver 的建议和正确方法。
我想过像这样从 BroadCastReceiver 访问 Repository:
RepositoryMain.getSingletonInstance().setResponse(state);
最佳答案
您需要定义单一事实来源 (SSoT)。在您的情况下,它是 Repository
(如果 Repository
封装了 db 持久性存储,SSoT 就是 db)。现在您需要通过 SSoT(Repository
)实现从接收器到 View 的数据流,如下例所示:
接收器实现
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();
}
}
Activity
有接收者数据和Repository
的绑定(bind)
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);
}
}
关于java - 在 Viewmodel 中访问 BroadCastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51490558/