[英]Dagger 2 field injection is not working in Android
The issue is that I try to use field injection with Dagger 2, but at runtime field, that should be injected, always is null
. 问题是我尝试将字段注入与Dagger 2一起使用,但是在运行时应该注入的字段始终为null
。 Also I try to use MVVM pattern. 我也尝试使用MVVM模式。 Here is my code: 这是我的代码:
ProfileActivity.java: ProfileActivity.java:
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "ProfileActivity: onStart: ");
final ProfileViewModel profileViewModel
= ViewModelProviders.of(this).get(ProfileViewModel.class);
profileViewModel.init();
profileViewModel.getUser().observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
if (user != null) {
Log.d(TAG, "ProfileActivity: onStart: " + user.toString());
} else {
Log.d(TAG, "ProfileActivity: onStart: user == null");
}
}
});
}
ProfileViewModel.java: ProfileViewModel.java:
public class ProfileViewModel extends ViewModel {
private LiveData<User> user;
@Inject
UserRepository userRepository;
public ProfileViewModel() {
Log.d(TAG, "ProfileViewModel: Constructor: ");
}
public void init() {
Log.d(TAG, "ProfileViewModel: init: ");
user = userRepository.getUser();
}
public LiveData<User> getUser() {
Log.d(TAG, "ProfileViewModel: getUser: ");
return user;
}
}
UserRepository.java: UserRepository.java:
@Singleton
public class UserRepository {
private LiveData<User> user;
@Inject
public UserRepository() {
Log.d(TAG, "UserRepository: Constructor: ");
}
public LiveData<User> getUser() {
Log.d(TAG, "UserRepository: getUser: ");
if (user != null) {
return user;
} else {
// There should be userDao.load() call,
// but it had been omitted for brevity.
MutableLiveData<User> user = new MutableLiveData<>();
user.setValue(DB.getUser());
return user;
}
}
}
MyApplication.java: MyApplication.java:
public class MyApplication extends MultiDexApplication implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerMyApplicationComponent.create().inject(this);
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
MyApplicationModule.java: MyApplicationModule.java:
@Module
public abstract class MyApplicationModule {
@ContributesAndroidInjector
abstract ProfileActivity contributeActivityInjector();
}
MyApplicationComponent.java: MyApplicationComponent.java:
@Component(modules = { AndroidInjectionModule.class, MyApplicationModule.class})
@Singleton
public interface MyApplicationComponent extends AndroidInjector<MyApplication> {
void inject(ProfileActivity profileActivity);
}
At runtime I can see the next logs: 在运行时,我可以看到以下日志:
ProfileActivity: onStart:
ProfileViewModel: Constructor:
ProfileViewModel: init:
And the app crashes on user = userRepository.getUser();
并且应用程序在user = userRepository.getUser();
上崩溃user = userRepository.getUser();
inside ProfileViewModel
's init()
method. 在ProfileViewModel
的init()
方法中。
It means that UserRepository
had not been injected. 这意味着尚未注入UserRepository
。 Also it is indicated by missing UserRepository: Constructor:
log. 此外,它还通过缺少UserRepository: Constructor:
日志来指示。
Where is my mistake? 我的错误在哪里? Thank you. 谢谢。
Basically what you need to do is to use ViewModel Factory
to pass injected UserRepository
into your ViewModels
constructor, initialize it and then you will be able to use it. 基本上,您需要做的是使用ViewModel Factory
将注入的UserRepository
传递到ViewModels
构造函数中,对其进行初始化,然后就可以使用它了。 You cannot use field or parameter injections in ViewModels
. 您不能在ViewModels
使用字段或参数注入。
I would suggest you to follow this article: Add the new ViewModel to your MVVM 我建议您遵循本文: 将新的ViewModel添加到您的MVVM中
It provides enough sufficient information to begin using Dagger 2 with Architecture Components. 它提供了足够的信息来开始将Dagger 2与Architecture Components一起使用。
Hope it helps. 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.