web-dev-qa-db-fra.com

Observez LiveData du service de premier plan

J'ai un référentiel qui contient l'objet LiveData et est utilisé à la fois par l'activité et un service de premier plan via un ViewModel. Lorsque je commence à observer l'activité, tout fonctionne comme prévu. Cependant, l'observation du service ne déclenche pas l'observation. C'est le code que j'utilise

class MyService: LifecycleService() {
     lateinit var viewModel: PlayerServiceViewModel

     override fun onCreate() {
          viewModel = MyViewModel(applicationContext as Application)
     }

     override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
          viewModel.getLiveData().observe(this, Observer { data ->
            // Do something with the data
        })
     }
}

Des idées pourquoi cela ne fonctionne pas et je ne reçois pas les données?

11
Ilya Sosis

J'ai utilisé ViewModel avec LiveData dans LifecycleActivity et Fragments cela fonctionne et observe les données comme prévu.

En venant à votre problème, lorsque vous créez nouveaViewModel à partir de Service ou tout autre Activity il crée nouvelle instance de toutes les LiveData et autres dépendances requises pour que ViewModel interroge depuis le référentiel et finalement DAO. Si vous n'utilisez pas le même DAO pour les deux ViewModels, votre LiveData peut ne pas se mettre à jour car il observe sur différent instance de DAO .

J'ai utilisé Dagger2 dans mon projet de maintenance des instances Singleton pour DAO et autres dépendances courantes. Vous pouvez donc essayer de créer votre référentiel et DAO singleton pour le garder cohérent dans l'ensemble de l'application.

Je l'ai essayé avec Services avec LifecycleService avec le même flux et cela a fonctionné pour moi.

J'ai obtenu la sortie suivante lorsque les données ont changé de forme nulle en données extraites

D/ForegroundService: onStartCommand: Resource{status=LOADING, message='null', data=null}
D/ForegroundService: onStartCommand: Resource{status=SUCCESS, message='null', data=TVShow(id=14,...

Au début, il montrait des données nulles car les données n'étaient pas présentes dans la base de données Après avoir extrait les données du réseau et mis à jour dans la base de données Observer les données observées automatiquement.

Élaboré en utilisant le code suivant

public class ForegroundService extends LifecycleService {

    private static final String TAG = "ForegroundService";

    private TVShowViewModel tvShowViewModel;
    private TVShow tvShow;

    @Inject TVShowDataRepo tvShowDataRepo;

    @Override
    public void onCreate() {
        super.onCreate();

        AndroidInjection.inject(this);
        tvShowViewModel = new TVShowViewModel(tvShowDataRepo);
        tvShowViewModel.init(14);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        tvShowViewModel.getTVShow().observe(this, tvShowResource -> {
            Log.d(TAG, "onStartCommand: " + tvShowResource);
        });
        return super.onStartCommand(intent, flags, startId);
    }
}
16
adityakamble49