Les meilleures pratiques pour Android MVVM startActivity
Je suis de la construction d'une Application Android utilisant MVVM et la liaison de données. Et j'ai une fonction à l'intérieur de mon ViewModel qui démarre une Activité.
Est-il normal d'avoir un onClick appel à l'intérieur d'un ViewModel?
Comme ça.
public class MyViewModel {
public void onClick(View view, long productId) {
Context context = view.getContext();
Intent intent = new Intent(context, ProductDetailActivity.class);
intent.putExtra("productId", productId);
context.startActivity(intent);
}
}
Et dans mon XML:
...
android:onClick="@{(v) -> viewModel.onClick(v, viewModel.product.id)}">
Ou serait-il une meilleure pratique pour la déplacer vers la Vue et de l'appeler à partir d'EventBus ou Rx et ont seulement POJO dans mon ViewModel?
OriginalL'auteur Felipe Kenji Shiba | 2016-11-07
Vous devez vous connecter pour publier un commentaire.
La réponse à votre question-quel est votre objectif?
Si vous souhaitez utiliser MVVM pour la séparation des préoccupations de sorte que vous pouvez unité de tester votre
Viewmodel
alors vous devriez essayer de garder tout ce qui nécessite unContext
séparé de votreViewmodel
. LeViewmodel
contient le noyau de la logique métier de votre application et ne devrait pas avoir de dépendances externes.Cependant j'aime où l'on va 🙂 Si la décision dont l'Activité est ouverte réside dans la Vue, c'est très très dur d'écrire un test Unitaire. Cependant, vous pouvez passer un objet dans le
Viewmodel
qui effectue lastartActivity()
appel. Maintenant, dans votre de test de l'Unité vous pouvez tout simplement se moquer de cet objet et de vérifier que la bonneActivity
est ouvertVous avez raison dans une certaine mesure. La question est de savoir quoi ne voulez atteindre. Pour moi la chose la plus importante est la testabilité. Si j'ai une dépendance à
View
ouContext
je ne peux vérifier à l'aide de Robolectric. Ces tests sont lents et nécessitent beaucoup de frais généraux. Donc ce que je cherche, c'est la plaine de l'Unité de test qui s'exécutent dans une fraction du temps un sont faciles à mettre en œuvre. La dépendance à la liaison de données de la bibliothèque ne diminue en rien cette.Donc, il n'y a aucune façon de mettre en œuvre une telle fonctionnalité. Je ne veux pas garder Contexte dans ma classe ViewModel, car il peut créer des fuites de Mémoire. Ni que je veux passer toute référence. Donc, si je veux passer à quelque ressource de Chaîne à partir de view viewModel ou je veux appeler une méthode en Vue de lancer une activité, alors comment puis-je la mettre en œuvre.
Vous pouvez faire quelque chose de similaire à ceci: stackoverflow.com/questions/31883415/... Donc ce que vous voulez faire est de passer une couche d'abstraction dans votre Dernier ou de l'animateur. Cette abstraction(interface) pourrait avoir une méthode
String getString(@StringRes int id)
. Et dans la mise en œuvre concrète de cette interface, vous pouvez implémenter lesgetString
et peut déléguer ce contexte. getString(). De cette façon, ce Dernier ne voit qu'une abstraction qui vous pourriez maquette pour testerMerci pour la réponse. En fait je connais déjà cette approche, et je suis de l'utiliser. Je ne suis pas vraiment concerné par les tests. Mon seul souci est de ne pas utiliser toute référence à vue parce que cela peut conduire à des fuites de mémoire et je n'en veux pas. Alors, dites-moi si nous utilisons une interface en œuvre en vue et référencé par ViewModel d'obtenir ou de définir des données en Vue, serait-il conduire à la fuite de mémoire?
OriginalL'auteur Kaskasi
C'est absolument parfait pour le mettre à l'intérieur
ViewModel
, cependant, vous devez définir votreViewModel
deActivity
/Fragment
.Voici quelques liens que vous pouvez suivre pour apprendre architecture MVVM.
Approche Android avec MVVM
Android MVVM
https://github.com/ivacf/archi
Personnes-MVVM
MVVM sur Android: Ce que Vous Devez Savoir
Je crois que les choses les plus importantes sur le modèle MVVM est la séparation de la logique entre les couches, en conséquence, devrait être responsable de la gestion de l'INTERFACE utilisateur et rien de plus! Donc, Dans ce cas, je crois que Modèle de Vue d'avoir une référence au contexte de l'application est moins nocif que de forcer l'affichage de faire aucune INTERFACE utilisateur des tâches. BTW, il y a de nombreux autres cas que nous avons peut-être besoin de contexte dans le ViewModel c'est pourquoi Android est une version de ViewModel qui a contexte!
pensé que vous étiez censé ne pas avoir de android paquets dans le viewmodel?
OriginalL'auteur Ravi Rupareliya
La façon dont je le fais, c'est, dans votre ViewModel:
Cela vous permet de vérifier la classe de l'Activité a commencé, et les données transmises dans le Bundle. Puis, dans votre Activité, vous pouvez ajouter ce code:
OriginalL'auteur gahfy
Que le principe de MVVM souligne que la seule Vue (activité/fragment) contient la référence au ViewModel et le ViewModel ne devrait pas tenir de référence à tout point de Vue.
Dans votre cas, pour démarrer une activité, je vais faire comme ceci:
MyViewModel.class
Et dans votre MainActivity.class
enfin, dans votre activity_main.xml
OriginalL'auteur lehongphucit
Que par la liaison de données de la documentation.
Il y a 2 façons de le faire:
1- MethodReferences : Vous devez passer l'affichage en tant que paramètre à la fonction, ou vous obtiendrez une erreur de compilation.
Si vous allez utiliser cette façon de faire une catégorie distincte comme exemple ici, qui gèrent de tels événements.
MyHandler
XML
2- Auditeur liaisons : Vous n'avez pas besoin de passer de la vue comme un exemple ici.
Mais si vous voulez startActivity faire de votre viewModel s'étend AndroidViewModel et vous allez utiliser l'applicaion objet.
ViewModel
XML
OriginalL'auteur Moaz Rashad