如何在 Android 中使用 Dagger2 将字符串传递给 ViewModel/Repository class?
How to pass a String to a ViewModel/Repository class using Dagger2 in Android?
这是我的片段class:
public class MyFragment extends DaggerFragment {
@Inject MyViewModelFactory factory;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}
}
现在是 MyViewModel
class:
public class MyViewModel extends ViewModel {
private MutableLiveData<User> liveData;
@Inject
MyViewModel(MyRepository repository) {
userLiveData = repository.addUserToLiveData();
//Here I need the value of that String "123"
}
LiveData<User> getUserLiveData() {
return liveData;
}
}
还有这个MyRepository
class:
@Singleton
class MyRepository {
private Retrofit retrofit;
@Inject
MyRepository(Retrofit retrofit) {
//Or here I need the value of that String "123"
}
MutableLiveData<User> addUserToLiveData() {
//Make api call using retrofit
}
}
也请看看我的AppModule
class:
@Module
public class AppModule {
@Singleton
@Provides
static Retrofit provideRetrofit(){
return new Retrofit.Builder()... //Initialize retrofit
}
}
在 MyViewModelModule
class:
@Module
abstract class MyViewModelModule {
@Binds
abstract ViewModelProvider.Factory bindMyViewModelFactory(MyViewModelFactory factory);
@Binds
@IntoMap
@ViewModelKey(MyViewModel.class)
abstract ViewModel provideMyViewModel(MyViewModel viewModel);
}
我尝试过在 ViewModel/repository 构造函数中添加字符串,但没有成功。请帮助我将 uid
传递给 ViewModel 或存储库 class。谢谢!
一种可能的解决方案是每个视图模型有 1 个工厂,然后将 UID 设置为工厂,然后工厂将其传递给视图模型
class MyViewModelFactory @Inject constructor(
private val repository: Repository
): ViewModelProvider.Factory {
lateinit var uid: String
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
MyViewModel(
repository,
uid
) as T
} else {
throw IllegalArgumentException("Unknown ViewModel class [$modelClass]")
}
}
然后
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
factory.setUid(uid);
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}
编辑:在Java
public final class MyViewModelFactory implements Factory {
private final Repository repository;
private String uid;
@Inject
public MyViewModelFactory(Repository repository) {
this.repository = repository;
}
@NotNull
public ViewModel create(@NotNull Class modelClass) {
if (modelClass.isAssignableFrom(MyViewModel.class)) {
return new MyViewModel(repository, uid);
} else {
throw (Throwable)(new IllegalArgumentException("Unknown ViewModel class [" + modelClass + ']'));
}
}
public void setUid(@NonNull final String uid) {
this.uid = uid;
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
factory.setUid(uid);
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}
这是我的片段class:
public class MyFragment extends DaggerFragment {
@Inject MyViewModelFactory factory;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}
}
现在是 MyViewModel
class:
public class MyViewModel extends ViewModel {
private MutableLiveData<User> liveData;
@Inject
MyViewModel(MyRepository repository) {
userLiveData = repository.addUserToLiveData();
//Here I need the value of that String "123"
}
LiveData<User> getUserLiveData() {
return liveData;
}
}
还有这个MyRepository
class:
@Singleton
class MyRepository {
private Retrofit retrofit;
@Inject
MyRepository(Retrofit retrofit) {
//Or here I need the value of that String "123"
}
MutableLiveData<User> addUserToLiveData() {
//Make api call using retrofit
}
}
也请看看我的AppModule
class:
@Module
public class AppModule {
@Singleton
@Provides
static Retrofit provideRetrofit(){
return new Retrofit.Builder()... //Initialize retrofit
}
}
在 MyViewModelModule
class:
@Module
abstract class MyViewModelModule {
@Binds
abstract ViewModelProvider.Factory bindMyViewModelFactory(MyViewModelFactory factory);
@Binds
@IntoMap
@ViewModelKey(MyViewModel.class)
abstract ViewModel provideMyViewModel(MyViewModel viewModel);
}
我尝试过在 ViewModel/repository 构造函数中添加字符串,但没有成功。请帮助我将 uid
传递给 ViewModel 或存储库 class。谢谢!
一种可能的解决方案是每个视图模型有 1 个工厂,然后将 UID 设置为工厂,然后工厂将其传递给视图模型
class MyViewModelFactory @Inject constructor(
private val repository: Repository
): ViewModelProvider.Factory {
lateinit var uid: String
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
MyViewModel(
repository,
uid
) as T
} else {
throw IllegalArgumentException("Unknown ViewModel class [$modelClass]")
}
}
然后
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
factory.setUid(uid);
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}
编辑:在Java
public final class MyViewModelFactory implements Factory {
private final Repository repository;
private String uid;
@Inject
public MyViewModelFactory(Repository repository) {
this.repository = repository;
}
@NotNull
public ViewModel create(@NotNull Class modelClass) {
if (modelClass.isAssignableFrom(MyViewModel.class)) {
return new MyViewModel(repository, uid);
} else {
throw (Throwable)(new IllegalArgumentException("Unknown ViewModel class [" + modelClass + ']'));
}
}
public void setUid(@NonNull final String uid) {
this.uid = uid;
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
String uid = "123"; //How to pass this String??
factory.setUid(uid);
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);
LiveData<User> liveData = viewModel.getUserLiveData();
}