作者:尼古拉斯Ga | 来源:互联网 | 2023-01-31 20:34
我一直在阅读有关Android引入的新架构组件的信息,但我无法弄清楚其工作原理:
ViewModelProviders.of(Activity).get(Class)
最初,我认为它调用默认构造函数并返回一个ViewModel对象,然后使用该对象实例化。一个init()方法
public class UserProfileViewModel extends ViewModel {
private String userId;
private User user;
public void init(String userId) {
this.userId = userId;
}
public User getUser() {
return user;
}
}
摘录自指南:https : //developer.android.com/topic/libraries/architecture/guide.html
但是,在指南的后面有以下代码段:
public class UserProfileViewModel extends ViewModel {
private LiveData user;
private UserRepository userRepo;
@Inject // UserRepository parameter is provided by Dagger 2
public UserProfileViewModel(UserRepository userRepo) {
this.userRepo = userRepo;
}
public void init(String userId) {
if (this.user != null) {
// ViewModel is created per Fragment so
// we know the userId won't change
return;
}
user = userRepo.getUser(userId);
}
那么ViewModelProvider如何知道调用提供的构造函数?还是看到只有1个构造函数并调用它?例如,如果有两个构造函数,将会发生什么?
我尝试挖掘代码,发现的是:
@Override
public T create(Class modelClass) {
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
return super.create(modelClass);
}
在DefaultFactory
班级里面ViewModelProviders.java
。但是,这使我更加困惑。getConstructor(Application.class)
当ViewModel
对象没有使用Application作为参数的构造函数时,它怎么工作?
1> Nikola Despo..:
在代码段中,有一个条件可以检查modelClass是否为AndroidViewModel
(inherits ViewModel
)类型,而该构造函数采用Application
参数。这更像是排他性的情况,它省去了Factory
查找与特定参数匹配的构造函数的过程。该提供程序在创建时会查找与提供程序参数匹配的构造函数:
public class ViewModelParameterizedProvider {
private AtomicBoolean set = new AtomicBoolean(false);
private ViewModelStore viewModelStore = null;
static ViewModelParameterizedProvider getProvider() {
return new ViewModelParameterizedProvider();
}
@MainThread
public static ViewModelProvider ofSupportFragment(Fragment fragment, Object... params) {
return getProvider().of(fragment).with(params);
}
@MainThread
public static ViewModelProvider ofActivity(FragmentActivity fragmentActivity, Object... params) {
return getProvider().of(fragmentActivity).with(params);
}
@MainThread
public static ViewModelProvider ofFragment(android.app.Fragment fragment, Object... params) {
return getProvider().of(fragment).with(params);
}
private ViewModelParameterizedProvider of(Fragment fragment) {
checkForPreviousTargetsAndSet();
viewModelStore = ViewModelStores.of(fragment);
return this;
}
private ViewModelParameterizedProvider of(android.app.Fragment fragment) {
FragmentActivity fragAct = (FragmentActivity) fragment.getActivity();
return of(fragAct);
}
private ViewModelParameterizedProvider of(FragmentActivity activity) {
checkForPreviousTargetsAndSet();
viewModelStore = ViewModelStores.of(activity);
return this;
}
private ViewModelProvider with(Object... constructorParams) {
return new ViewModelProvider(viewModelStore, parametrizedFactory(constructorParams));
}
private void checkForPreviousTargetsAndSet() {
if (set.get()) {
throw new IllegalArgumentException("ViewModelStore already has been set. Create new instance.");
}
set.set(true);
}
private ViewModelProvider.Factory parametrizedFactory(Object... constructorParams) {
return new ParametrizedFactory(constructorParams);
}
private final class ParametrizedFactory implements ViewModelProvider.Factory {
private final Object[] mConstructorParams;
ParametrizedFactory(Object... constructorParams) {
mCOnstructorParams= constructorParams;
}
@Override
public T create(Class modelClass) {
if (modelClass == null) {
throw new IllegalArgumentException("Target ViewModel class can not be null")
}
Log.w("ParametrizedFactory", "Don't use callbacks or Context parameters in order to avoid leaks!!")
try {
if (mCOnstructorParams== null || mConstructorParams.length == 0) {
return modelClass.newInstance();
} else {
Class>[] classes = new Class>[mConstructorParams.length];
for (int i = 0; i
这是科特林版本。这是有关该主题的更多内容