Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在Viewmodel中访问广播接收器_Android_Mvvm_Viewmodel_Android Architecture Components_Android Livedata - Fatal编程技术网

Android 在Viewmodel中访问广播接收器

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的最佳

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

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

如果我管理broadcastReceiver的生命周期,它应该不会导致任何问题那么,将接收到的数据从FCM传递到存储库的MediaLiveData的最佳方式是什么?我使用MediaLiveData,因为我添加了不同的LiveData源(API请求和FCM)

如能提供建议和正确的实施方法,将不胜感激

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

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