web-dev-qa-db-ja.com

ViewmodelでBroadCastReceiverにアクセスする

データをbroadcastReceiverからViewModelに渡す正しい方法を選択するのに苦労しており、そこからデータをリポジトリに渡してLiveDataを更新します。 FCMプッシュ通知を使用しており、ActivityLifecycleを使用するローカルのbroadCastReceiverを持っています。

BroadcastReceiverからViewModelにアクセスすることは悪い習慣であることがわかりましたが、なぜかわかりません。

BroadcastReceiverのライフサイクルを管理している場合、問題は発生しません... FCMからリポジトリのMediatorLiveDataに受信データを渡すための最良の方法は何ですか?異なるLiveDataソースを追加するため、MediatorLiveDataを使用します( APIリクエストとFCM)。

アドバイスとbroadCastReceiverを実装する正しい方法に感謝します。

BroadCastReceiverから次のようにリポジトリにアクセスすることを考えました。

RepositoryMain.getSingletonInstance().setResponse(state);
8

単一の真実のソースSSoT)を定義する必要があります。あなたの場合、それはRepositoryRepositoryがdb永続ストレージをカプセル化する場合、SSoTそれはdbです)。次の例のように、レシーバーから表示するデータフローを実装してSSoTRepository)を実装する必要があります。

レシーバーの実装

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

アクティビティ

レシーバーデータと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);
    }
}
17
XIII-th