2017-05-26 148 views
11

我正在关注this文档以了解LiveData和ViewModel。 在文档,视图模型类有构造函数,例如,Android ViewModel没有零参数构造函数

public class UserModel extends ViewModel { 
    private MutableLiveData<User> user; 

    @Inject UserModel(MutableLiveData<User> user) { 
    this.user = user; 
    } 

    public void init() { 
    if (this.user != null) { 
     return; 
    } 
    this.user = new MutableLiveData<>(); 
    } 

    public MutableLiveData<User> getUser() { 
    return user; 
    } 
} 

然而,当我运行代码,我得到异常:了java.lang.RuntimeException:

final UserViewModelviewModel = ViewModelProviders.of(this).get(UserViewModel.class); 

产生的原因:无法创建类的实例UserViewModel 引起:java.lang.InstantiationException: java.lang.Class 没有零参数构造函数

回答

15

使用ViewModelProviders初始化ViewModel的子类时,默认情况下,它期望UserModel类具有零参数构造函数。 在你的情况你的构造函数的参数来解决这个MutableLiveData<User> user

一种方法是有一个默认的无参数的构造函数为您UserModel

否则,如果你想有一个非零参数的构造函数为您ViewModel类,你可能必须创建一个自定义ViewModelFactory类来初始化您的ViewModel实例,该实例将实现ViewModelProvider.Factory接口。

我还没有尝试过这个,但这里是从谷歌优秀样本链接相同:github.com/googlesamples/android-architecture-components。 具体签这个类GithubViewModelFactory.java

+1

讨论:https://www.reddit.com/ R/androiddev /评论/ 6bw1jj/architecture_components_introduction_google_io_17 / –

1

ViewModelFactory,将提供我们从ViewModelModule

public class ViewModelFactory implements ViewModelProvider.Factory { 
    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels; 

    @Inject 
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) { 
     this.viewModels = viewModels; 
    } 

    @Override 
    public <T extends ViewModel> T create(Class<T> modelClass) { 
     Provider<ViewModel> viewModelProvider = viewModels.get(modelClass); 

     if (viewModelProvider == null) { 
      throw new IllegalArgumentException("model class " + modelClass + " not found"); 
     } 

     return (T) viewModelProvider.get(); 
    } 
} 

ViewModelModule负责结合各地视图模型类为
Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels

@Module 
public abstract class ViewModelModule { 

    @Binds 
    @IntoMap 
    @ViewModelKey(UserViewModel.class) 
    abstract ViewModel userViewModel(UserViewModel userViewModel); 

    //Others ViewModels 
} 

ViewModelKey右视图模型是一个注释作为地图中的钥匙使用,看起来像

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@MapKey 
@interface ViewModelKey { 
    Class<? extends ViewModel> value(); 
} 

现在你可以从图中创建视图模型,并满足所有必要的相关解决此

public class UserViewModel extends ViewModel { 
    private UserFacade userFacade; 

    @Inject 
    public UserViewModel(UserFacade userFacade) { // UserFacade should be defined in one of dagger modules 
     this.userFacade = userFacade; 
    } 
} 

实例化视图模型

public class MainActivity extends AppCompatActivity { 

    @Inject 
    ViewModelFactory viewModelFactory; 
    UserViewModel userViewModel; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     ((App) getApplication()).getAppComponent().inject(this); 

     userViewModel = ViewModelProviders.of(this, viewModelFactory).get(UserViewModel.class); 

    } 
} 
相关问题