I am trying to write a generic base activity, that specifies it's ViewModel type a generic parameter:
abstract class BaseActivity<T : ViewModel> : AppCompatActivity()
Now I am trying to write a lazy initialized property for my ViewModel:
val viewModel by lazy { ViewModelProviders.of(this, getFactory()).get(T) }
The error that is displayed is Type Parameter T is not an expression
Also using ::class
or ::class.java
did not help. Can anyone explain the problem?
EDIT: I tried to use a reified inline function like this:
inline fun <reified T : ViewModel?> AppCompatActivity.obtainViewModel(factory: ViewModelProvider.Factory): T {
return ViewModelProviders.of(this, factory).get(T::class.java)
}
And used it like this:
abstract class BaseActivity<T> : AppCompatActivity() {
val viewModel by lazy { obtainViewModel<T>(getFactory())
}
Now I get the error, that T cannot be used as a reified parameter.
EDIT2: The best solution so far seems to be this: Link, but its overhead to implement the abstract token in every extending class.
Your class has a type parameter T
, which unfortunately gets erased at runtime. As a result, the call get(T)
does not work (I guess the method expects a Class
actually?).
You seem to have already noticed that and thus tried to fix it with encapsulating the handling into a method using reified
type. Yet, you cannot pass T
as a reified parameter since this type will already be erased when the reified
-typed method is called. As a result, obtainViewModel<T>
will not work either. What you can do, is using T
for ordinary generic methods, which the following demonstrates:
class Typed<T> {
val lazyProp by lazy {
listOf<T>()
}
}
maybe a bit late, but I guess this could be the elegant way to achieve it:
abstract class BaseActivity<T : ViewModel>(
private var modelClass: Class<T>) : AppCompatActivity() {
val viewModel by lazy {
ViewModelProviders.of(this, getFactory()).get(modelClass)
}
}
and then
class SampleActivity : BaseActivity<SampleViewModel>(SampleViewModel::class.java) {
// use viewModel from here
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With