2017-05-26 66 views
11

LiveData ve ViewModel hakkında bilgi edinmek için this belgelerini takip ediyorum. java.lang.RuntimeException:Android ViewModel sıfır argüman yapıcı yok

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

Neden Olduğu: doc olarak , ViewModel sınıf I kodu çalıştırdığınızda, özel durum almak Ancak, örneğin

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; 
    } 
} 

Oluşturucu sahip: java.lang.InstantiationException: neden Olduğu sınıf UserViewModel bir örneğini oluşturulamaz java.lang.Class hiçbir sıfır argüman yapıcı sahiptir

cevap

15

'un alt sınıflarını ViewModelProviders kullanarak başlatırken, varsayılan olarak UserModel sınıfınızın sıfır bağımsız değişken yapıcısına sahip olmasını bekler. Yapıcınızda sizin durumda size ViewModel sınıf için olmayan bir sıfır argüman yapıcı sahip olmak istiyorsanız Aksi takdirde UserModel

için varsayılan hiçbir arg yapıcı olması argüman Bunu düzeltmek için MutableLiveData<User> user

Tek yön hal almıştır ki, sizi ViewModelProvider.Factory arabirimini uygulayacak olan ViewModel örneğinizi başlatmak için özel bir ViewModelFactory sınıfı oluşturmanız gerekebilir.

Bunu henüz denemedim, ancak işte bunun için google'dan mükemmel örnekle bağlantı: github.com/googlesamples/android-architecture-components. Özellikle 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 içine ViewModel sınıfları yerinden bağlanma sorumludur bize bir sağ ViewModel sağlayacak bu sınıfı GithubViewModelFactory.java

+1

Tartışma gerekli tüm bağımlılıkları ViewModel oluşturmak ve tatmin edebiliyoruz: https://www.reddit.com/ r/androiddev/yorum/6bw1jj/architecture_components_introduction_google_io_17 / –

1

ViewModelFactory ödeme ek açıklama olduğunu Harita içinde bir anahtar olarak kullanmak ve

01 gibi görünüyor
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@MapKey 
@interface ViewModelKey { 
    Class<? extends ViewModel> value(); 
} 

Şimdi grafikten bu çevrede

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; 
    } 
} 

başlatmasını ViewModel

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); 

    } 
}