web-dev-qa-db-fra.com

Accès à BroadCastReceiver dans Viewmodel

J'ai du mal à choisir la bonne façon de transmettre des données de broadcastReceiver à ViewModel et à partir de là, je passe des données à mon référentiel et met à jour LiveData. J'utilise les notifications FCM Push et j'ai broadCastReceiver local qui utilise ActivityLifecycle.

J'ai trouvé que c'est une mauvaise pratique d'accéder à ViewModel à partir de BroadcastReceiver, mais je ne sais pas pourquoi?

Si je gère le cycle de vie de broadcastReceiver, cela ne devrait pas poser de problème ... Alors, quelle est la meilleure façon de transmettre les données reçues de FCM à MediatorLiveData de mon référentiel? J'utilise MediatorLiveData, car j'ajoute différentes sources LiveData ( Demande API et FCM).

Serait reconnaissant pour des conseils et une manière correcte d'implémenter broadCastReceiver.

J'ai pensé à accéder au référentiel à partir de BroadCastReceiver, comme ceci:

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

Vous devez définir source unique de vérité (SSoT). Dans votre cas, il Repository (si Repository encapsule le stockage de persistance db, SSoT c'est db). Maintenant, vous devez implémenter le flux de données du récepteur pour voir à travers SSoT (Repository) comme dans l'exemple ci-dessous:

Implémentation du récepteur

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

Dépôt

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

Voir le modèle

public class MyViewModel extends ViewModel {

    public LiveData<MyData> getData() {
        // for simplicity return data directly to view
        return Repository.instance().getData();
    }
}

Activité

Il y a liaison des données du récepteur et 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