The*_*mer 48 android android-lifecycle dagger-2
我有一个ViewModel类,就像在Architecture指南的Connecting ViewModel和repository部分中定义的那样.当我运行我的应用程序时,我得到运行时异常.有谁知道怎么解决这个问题?我应该不注入ViewModel吗?有没有办法告诉使用Dagger创建模型?ViewModelProvider
public class DispatchActivityModel extends ViewModel {
private final API api;
@Inject
public DispatchActivityModel(API api) {
this.api = api;
}
}
Run Code Online (Sandbox Code Playgroud)
引起:java.lang.InstantiationException:java.lang.Class在java.lang.Class.newInstance(Native Method)的android.arch.lifeModelProvider $ NewInstanceFactory.create(ViewModelProvider.java:143)中没有零参数构造函数在Android.arch.lifecycle.ViewModelProvider.get上的android.arch.lifecycle.ViewModelProviders $ DefaultFactory.create(ViewModelProviders.java:143)android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:128)(ViewModelProvider.java) :96)com.example.base.BaseActivity.onCreate(BaseActivity.java:65)at com.example.dispatch.DispatchActivity.onCreate(DispatchActivity.java:53)at android.app.Activity.performCreate(Activity.java: 6682)在android.app.Anstrumentation.callActivityOnCreate(Instrumentation.java:1118)的android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727). android.app.ActivityT上的app.ActivityThread.-wrap12(ActivityThread.java)在android.app.ActivityThread.main上的android.os.Handler.dispatchMessage(Handler.java:102)上的android.os.Looper.loop(Looper.java:154)处获取$ H.handleMessage(ActivityThread.java:1478) (ActivityThread.java:6121)
小智 85
你需要实现自己的ViewModelProvider.Factory.Google创建了一个示例应用,演示如何将Dagger 2与ViewModels连接.链接.你需要这5件事:
在ViewModel中:
@Inject
public UserViewModel(UserRepository userRepository, RepoRepository repoRepository) {
Run Code Online (Sandbox Code Playgroud)
定义注释:
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
Run Code Online (Sandbox Code Playgroud)
在ViewModelModule中:
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserViewModel.class)
abstract ViewModel bindUserViewModel(UserViewModel userViewModel);
Run Code Online (Sandbox Code Playgroud)
在片段中:
@Inject
ViewModelProvider.Factory viewModelFactory;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class);
Run Code Online (Sandbox Code Playgroud)
厂:
@Singleton
public class GithubViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public GithubViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
arg*_*iwi 25
今天我学会了一种避免为我的ViewModel课程编写工厂的方法:
class ViewModelFactory<T : ViewModel> @Inject constructor(
private val viewModel: Lazy<T>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T = viewModel.get() as T
}
Run Code Online (Sandbox Code Playgroud)
编辑:正如@Calin在评论中指出的那样,我们Lazy在上面的代码片段中使用Dagger ,而不是Kotlin的.
ViewModel您可以将一个泛型ViewModelFactory注入到您的活动和片段中,而不是注入它,并获取任何实例ViewModel:
class MyActivity : Activity() {
@Inject
internal lateinit var viewModelFactory: ViewModelFactory<MyViewModel>
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
this.viewModel = ViewModelProviders.of(this, viewModelFactory)
.get(MyViewModel::class.java)
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
我AndroidInjection.inject(this)和dagger-android库一样使用,但您可以按照自己喜欢的方式注入活动或片段.剩下的就是确保您ViewModel从模块中提供:
@Module
object MyModule {
@JvmStatic
@Provides
fun myViewModel(someDependency: SomeDependency) = MyViewModel(someDependency)
}
Run Code Online (Sandbox Code Playgroud)
或者将@Inject注释应用于其构造函数:
class MyViewModel @Inject constructor(
someDependency: SomeDependency
) : ViewModel() {
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24207 次 |
| 最近记录: |