在 Viewmodel 中访问 BroadCastReceiver

Accessing BroadCastReceiver in Viewmodel

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

我发现从 BroadcastReceiver 访问 ViewModel 是不好的做法,但不确定为什么?

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

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

我考虑过从 BroadCastReceiver 访问 Repository,像这样:

RepositoryMain.getSingletonInstance().setResponse(state);

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

接收器实现

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

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

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

相关的 viewModel

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

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

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