Android 在Viewmodel中访问广播接收器
我正在努力选择正确的方式将数据从broadcastReceiver传递到ViewModel,然后从那里将数据传递到存储库并更新LiveData。我使用FCM推送通知,并有使用ActivityLifecycle的本地broadCastReceiver 我发现从BroadcastReceiver访问ViewModel是一种不好的做法,但不知道为什么 如果我管理broadcastReceiver的生命周期,它应该不会导致任何问题那么,将接收到的数据从FCM传递到存储库的MediaLiveData的最佳方式是什么?我使用MediaLiveData,因为我添加了不同的LiveData源(API请求和FCM) 如能提供建议和正确的实施方法,将不胜感激 我考虑过从BroadCastReceiver访问存储库,如下所示:Android 在Viewmodel中访问广播接收器,android,mvvm,viewmodel,android-architecture-components,android-livedata,Android,Mvvm,Viewmodel,Android Architecture Components,Android Livedata,我正在努力选择正确的方式将数据从broadcastReceiver传递到ViewModel,然后从那里将数据传递到存储库并更新LiveData。我使用FCM推送通知,并有使用ActivityLifecycle的本地broadCastReceiver 我发现从BroadcastReceiver访问ViewModel是一种不好的做法,但不知道为什么 如果我管理broadcastReceiver的生命周期,它应该不会导致任何问题那么,将接收到的数据从FCM传递到存储库的MediaLiveData的最佳
RepositoryMain.getSingletonInstance().setResponse(state);
您需要定义单一真相来源(SSoT)。在您的情况下,它是存储库
(如果存储库
封装了db持久性存储,那么SSoT就是db)。现在,您需要通过SSoT(存储库
)实现从接收器到视图的数据流,如下例所示:
接收机实现
真是太棒了!这是以类似的方式进行的,但是管理来源不同,我认为您的方式要好得多。然而,在使用MediatorLiveData实现业务逻辑之后,我觉得RxJava可能是未来更好的选择。使用该工具更容易链接不同的源。您使用RxJava for business logic而不是MediatorLiveData的经验如何?@ViktorVostrikov我还不熟悉RxJava,但它是在我的待办事项中编写的list@XIII-我遵循了这一点,但无法实现结果,在广播接收器中,更新livedata后,它不会触发存储库viewmodel。你能帮我解决这个问题吗?在BroadcastReceiver中创建一个公共可观测数据对象的好主意!对于生产,我建议将存储库交互移动到ViewModel,以处理网络和任何本地存储(如Room数据库)之间的所有数据请求。这违反了干净的体系结构。活动不应该了解任何关于存储库的信息,它应该只与ViewModel通信。ViewModel可以委托给存储库。
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();
}
}
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);
}
}