2

J'ai un ViewModel appelé RecipesViewModel. En général, je l'ai instancié ainsi:Instancier ViewModels directement, sans utiliser ViewModelProviders.of méthode

RecipesViewModel viewModel = ViewModelProviders.of(this, new ViewModelProvider.Factory() { 
      @Override 
      public <T extends ViewModel> T create(Class<T> modelClass) { 
       return (T) new RecipesViewModel(recipesRepository); 
      } 
     }).get(RecipesViewModel.class); 

Mais maintenant, je suis en utilisant dagger2 et je mets une annotation @Inject sur le constructeur de ce ViewModel, donc je suis en mesure d'injecter directement dans mon fragment, en utilisant injecteur de champ.

Ma question est: est-ce que je perds quelque chose en commençant le viewmodel de cette façon au lieu de ViewModelProviders.of? Mon ViewModel est déjà Scoped, donc une seule instance est créée en contexte.

L'autre option consiste à déplacer uniquement l'instantiation d'usine vers un module dagger2, mais s'il n'y a pas de problème, je préfère la première approche.

- EDIT -

lecture de la documentation android.arch.lifecycle.ViewModel, je suis un peu plus peur. Nous utilisons ViewModelProviders.of pour fournir un Scope (fragment ou activité). Si je l'instancie directement, quel sera le Scope?

ViewModel est une classe qui est responsable de la préparation et de la gestion les données pour une activité ou un fragment. Il gère également la communication de l'activité/du fragment avec le reste de l'application (par exemple, l'appel des classes de logique métier). Un ViewModel est toujours créé en association avec une étendue (un fragment ou une activité) et sera conservé tant que la portée est active. E.g. si c'est une activité, jusqu'à ce qu'elle soit terminée. En d'autres termes, cela signifie qu'un ViewModel ne sera pas détruit si le propriétaire est détruit pour un changement de configuration (par exemple une rotation). La nouvelle instance du propriétaire sera simplement reconnectée au ViewModel existant.

-/EDIT -

Le code RecipesViewModel montre ci-dessous:

@PerActivity 
public class RecipesViewModel extends ViewModel { 
    private static final String TAG = "RecipesViewModel"; 
    private final RecipesRepository recipesRepository; 

    private LiveData<List<Recipe>> recipes = null; 

    @Inject 
    public RecipesViewModel(RecipesRepository recipesRepository) { 
     this.recipesRepository = recipesRepository; 
    } 

    public final void loadAll() { 
     recipes = recipesRepository.getRecipes(); 
    } 

    public LiveData<List<Recipe>> getRecipes() { 
     return recipes; 
    } 
} 
+1

Sans expérimentation et lecture uniquement des documents et de ce que je sais sur les composants architecturaux, tout se résume à la façon dont vous gérez la portée. Si, par exemple, vous créez un nouveau composant dagger sur les modifications de configuration, le modèle de vue fourni par ce composant sera certainement différent de celui que vous aviez auparavant, car les étendues sont liées aux composants. Ce que je reçois des docs, c'est que cela ne se produit pas si vous utilisez '' ViewModelProviders.of''. Cela ne se produira pas non plus tant que le composant dague est le même - le viewmodel fourni est également le même. – Fred

+0

ViewModelProviders fournit un stockage qui est limité à l'activité ou au fragment en cours et transmis à l'instance suivante lors des modifications de configuration. Si vous déclarez votre ViewModel comme singleton global à la place, cela peut causer des problèmes car l'état sera partagé entre différentes activités ou fragments d'instances, et le ViewModel ne sera pas détruit avec l'Activité ou le Fragment. – BladeCoder

Répondre

0

Pour moi en ce moment (et je dois la recherche cela), mais l'injection d'un modèle de vue au lieu de l'utilisation de la fonctionnalité ViewModelProviders signifie que vous perdez une communication facile avec un fragment d'activité.

Par exemple from the docs ils fournissent un exemple d'une activité hébergeant 2 fragments. Si un fragment a besoin de parler à un autre, la méthode précédente consistait à maintenir une interface via l'activité qui devait également prendre en charge le cycle de vie de cette interface. Au lieu de cela, vous pouvez maintenant le récupérer à partir du repo de ViewModelProviders quand vous en avez besoin.