问题描述
我复制了带有Android体系结构组件,翻新,Dagger和数据绑定的MVVM的示例.我将此代码用作我的应用程序的起点,以便开始在Android应用程序开发中使用更好的架构.但是,请采用以下代码:
I copied an example of MVVM with Android Architecture Components, Retrofit, Dagger, and data binding. I am using this code as a starting point to my app in order to start using better architectures in Android app development. However, take these codes:
interface ViewModelInjector {
/**
* Injects required dependencies into the specified PostListViewModel.
* @param postListViewModel PostListViewModel in which to inject the dependencies
*/
fun inject(postListViewModel: PostListViewModel)
@Component.Builder
interface Builder {
fun build(): ViewModelInjector
fun networkModule(networkModule: NetworkModule): Builder
}
}
还有
class ViewModelFactory(private val activity: AppCompatActivity) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(PostListViewModel::class.java)) {
val db = Room.databaseBuilder(
activity.applicationContext,
AppDatabase::class.java,
"posts"
).build()
@Suppress("UNCHECKED_CAST")
return PostListViewModel(db.postDao()) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
还有
abstract class BaseViewModel : ViewModel() {
private val injector: ViewModelInjector = DaggerViewModelInjector
.builder()
.networkModule(NetworkModule)
.build()
init {
inject()
}
private fun inject() {
when (this) {
is PostListViewModel -> injector.inject(this)
}
}
}
主要问题是它被卡在PostListViewModel
上.我想以一种动态的方式来接受任何[Name]ViewModel
类.我确实使用Class<T>
尝试了一些方法,但是我不再有代码了.我也尝试搜索,但结果不理想.也许我没有搜索适当的术语.感谢您的指导.
The main problem is that it's stuck with PostListViewModel
. I'd like to make it in a dynamic way, accepting any kind of [Name]ViewModel
class. I did try some ways using Class<T>
, but I no longer have the code. I also tried searching but couldn't come with a good result. Maybe I didn't search for the proper terms. I appreciate any guidance.
推荐答案
最近我遇到了同样的问题,我发现了generic ViewModelFactory
,它是Java,但是..
Recently I had the same issue and I found a generic ViewModelFactory
, it's java but..
@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@NonNull
@SuppressWarnings("unchecked")
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我会放置参考链接,但是我找不到它.
I'd put the reference link, but I couldn't find it yet..
@Singleton
@Component(modules={ActivityModule.class, FragmentModule.class, AppModule.class})
public interface AppComponents {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(Application application);
AppComponents build();
}
void inject(Weather weatherApp);
}
现在,您对以上课程感兴趣的是AppModule.class
Now, what is in your interest from the class above should be AppModule.class
@Module(includes = {UserModelModule.class /* other model modules */})
public class AppModule {
// --- DATABASE INJECTION ---
@Provides
@Singleton
YourDatabase provideDatabase(Application application) {
return Room.databaseBuilder(application,
YourDatabase.class, "YourDatabase.db")
//.allowMainThreadQueries() // do NOT DO THIS IN REAL APPLICATIONs
.fallbackToDestructiveMigration()
.build();
}
@Provides
@Singleton
UserDao provideUserDao(YourDatabase database) { return database.userDao(); }
.
.
// other Daos that you will have (the above is an example from [https://developer.android.com/jetpack/docs/guide]
最后,我想您会想了解ModelModule类的外观
Last, I guess you'll want to see how ModelModule class looks like
@Module
public abstract class UserModelModule {
@Binds
@IntoMap
@ViewModelKey(UserViewModel.class)
abstract ViewModel bindUserProfileViewModel(UserViewModel repoViewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory);
}
这篇关于如何使此ViewModelFactory更灵活并接受不同种类的ViewModel类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!