2017-08-04 91 views
3

我正在试用来自Google的Architecture Components。具体来说,我想实现一个ViewModelProvider.Factory创建一个视图模型是需要构造函数的参数,就像这样:kotlin中的Android ViewModelProviderFactory

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

我的视图模型是这样的:

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

任何人知道如何避免到底讨厌的投:

return MyViewModel(handler) as T 
+1

你正在做一个危险的工作......客户端代码期望一个'T扩展ViewModel',但你给一个'MyViewModel'。当客户端代码使用特定类型的'T'时,你总是得到'ClassCastException',例如:'val model:T = factory.create(T :: class.java)' –

+0

这就是为什么我想知道替代方法:) – Entreco

+1

你可以使用反射来实例化ViewModel或使用第三个IoC容器来创建ViewModel。 –

回答

4

你可以写:

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

这将适用于接受Handler作为构造函数参数的任何类,如果该类没有正确的构造函数,将抛出NoSuchMethodException

+0

由于这应该被称为非常罕见,反射的代价似乎是合理的。本来希望有一些时髦的Kotlin好东西,但是这样做会。谢谢! – Entreco

+1

不幸的是,在这种情况下,像泛化的泛型类型的Kotlin好吃的东西不可用。由于类型删除,您只能强制投射或使用反射。此外,默认工厂已经使用反射来调用空的公共构造函数,所以成本大致相同。 – BladeCoder