2017-05-26 125 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); 

    } 
} 
相關問題