我一直在阅读有关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> 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 extends viewmodel> T create(Class<T> 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); }
在viewmodelProvIDers.java内部的DefaultFactory类内部.但是,这使我更加困惑.当viewmodel对象没有以Application为参数的构造函数时,getConstructor(Application.class)怎么工作?
解决方法:
在代码段中,有一个条件可以检查modelClass是否为AndroIDviewmodel类型(继承自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 extends viewmodel> T create(Class<T> 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 < mConstructorParams.length; i++) { classes[i] = mConstructorParams[i].getClass(); } return modelClass.getConstructor(classes).newInstance(mConstructorParams); } } catch (InstantiationException e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } catch (NoSuchMethodException e) { e.printstacktrace(); } catch (InvocationTargetException e) { e.printstacktrace(); } return null; } }}
这是kotlin version.
这是more read on the subject
以上是内存溢出为你收集整理的java-架构组件:ViewModelProvider如何知道要调用哪个构造函数?全部内容,希望文章能够帮你解决java-架构组件:ViewModelProvider如何知道要调用哪个构造函数?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)