代码之家  ›  专栏  ›  技术社区  ›  Yamashiro Rion

Dagger 2 field injection在Android中不起作用

  •  2
  • Yamashiro Rion  · 技术社区  · 7 年前

    问题是,我尝试在Dagger 2中使用字段注入,但在运行时,应该注入的字段总是 null 。我还尝试使用MVVM模式。这是我的代码:

    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:

    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;
        }
    }
    

    用户存储库。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;
            }
        }
    }
    

    我的应用程序。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:

    @Module
    public abstract class MyApplicationModule {
        @ContributesAndroidInjector
        abstract ProfileActivity contributeActivityInjector();
    }
    

    MyApplicationComponent。java:

    @Component(modules = { AndroidInjectionModule.class, MyApplicationModule.class})
    @Singleton
    public interface MyApplicationComponent extends AndroidInjector<MyApplication> {
        void inject(ProfileActivity profileActivity);
    }
    

    在运行时,我可以看到下一个日志:

    ProfileActivity: onStart:
    ProfileViewModel: Constructor:
    ProfileViewModel: init:
    

    应用程序崩溃 user = userRepository.getUser(); 在…内 ProfileViewModel init() 方法

    这意味着 UserRepository 没有注射。也可以通过缺失来表示 UserRepository: Constructor: 日志

    我的错在哪里?非常感谢。

    1 回复  |  直到 6 年前
        1
  •  5
  •   Tomas Jablonskis    7 年前

    基本上你需要做的是 ViewModel Factory 通过注入 UserRepository 进入您的 ViewModels 构造函数,初始化它,然后就可以使用它了。不能在中使用字段或参数注入 视图模型

    我建议您关注这篇文章: Add the new ViewModel to your MVVM

    它提供了足够的信息,可以开始在架构组件中使用Dagger 2。


    希望有帮助。