2017-08-04 2 views
3

J'expérimente avec le Architecture Components de Google. Plus précisément, je veux mettre en œuvre un ViewModelProvider.Factory pour créer un ViewModel qui prend les paramètres du constructeur, comme ceci:Android ViewModelProviderFactory dans kotlin

class MyFactory(val handler: Handler) : ViewModelProvider.Factory { 
    override fun <T : ViewModel?> create(modelClass: Class<T>?): T { 
     return MyViewModel(handler) as T 
    } 
} 

Mon ViewModel ressemble à ceci:

class MyViewModel(val handler: Handler) : ViewModel() 

Tout le monde sait comment éviter le casting méchant à la fin :

return MyViewModel(handler) as T 
+1

vous faites un travail dangereux ... le code client attend un 'T extends ViewModel' mais vous donnez un' MyViewModel'. Lorsque le code client utilise un type spécifique de 'T', vous avez toujours une' ClassCastException', par exemple: 'val model: T = factory.create (T :: class.java)' –

+0

C'est pourquoi je voudrais connaître un autre approche :) – Entreco

+1

vous pouvez utiliser la réflexion pour instancier le 'ViewModel' ou utiliser le 3ème conteneur IoC pour créer' ViewModel'. –

Répondre

4

Vous pouvez écrire:

class MyFactory(val handler: Handler) : ViewModelProvider.Factory { 
    override fun <T : ViewModel> create(modelClass: Class<T>): T { 
     return modelClass.getConstructor(Handler::class.java).newInstance(handler) 
    } 
} 

Ceci fonctionnera avec n'importe quelle classe acceptant un Handler comme argument constructeur et lancera NoSuchMethodException si la classe n'a pas le constructeur approprié.

+0

Puisque cela devrait être appelé très rarement, le coût de la réflexion semble raisonnable. J'aurais espéré quelques goodies géniaux Kotlin, mais cela fera l'affaire. Merci! – Entreco

+1

Les goodies Kotlin comme les types génériques réifiés ne sont malheureusement pas disponibles dans ce cas. En raison de l'effacement du type, vous ne pouvez forcer que le lancer ou utiliser la réflexion. De plus, la fabrique par défaut utilise déjà la réflexion pour invoquer le constructeur public vide, de sorte que le coût serait à peu près le même. – BladeCoder