java - 在 Viewmodel 中访问 BroadCastReceiver

标签 java android mvvm android-livedata android-architecture-components

我正在努力选择将数据从 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/

相关文章:

android - ACRA 集成和 Google 云端硬盘

android - LogCat 中的 libagl alphaPlaneWorkaround 错误消息

WPF MVVM : Notify property changed one property everytime some other property is changed

c# - ObservableCollection (ViewModel) 中的 MVVM ObservableCollection

c# - PropertyChangedEventHandler 和 NotifyCollectionChangedEventHandler 有什么区别?

java - 神秘失踪换行符

java - Quarkus 和 Keycloak/OIDC - NullPointerException

Android Studio - 多个开发人员使用 Google Maps API key

java - 数组(搜索最大值)

Java 和 GUI 选项