Dagger2 在 Presenter 层可以提供,但在 Model 层为 null
Dagger2 can provide on Presenter layer but null on Model layer
我正在尝试使用 MVP 模式和用于依赖注入的 Dagger 2 重构我的应用程序。
我创建了提供应用程序上下文的模块,我想获取上下文以获取模型层上的SharedPreferences
。
我在 Presenter 层上注入了 Context,它与 SharedPreference
一起工作,但是当我移动到模型层时,Dagger 在 Context
变量上注入了一个 null
值。
注入
@Inject
public Context mContext;
应用模块
AppModule 提供应用上下文
@Module
public class AppModule {
private App app;
public AppModule(App app){
this.app = app;
}
@Provides
public Context providesApp(){
return app.getApplicationContext();
}
}
申请
public class App extends Application {
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.mainModule(new MainModule())
.build();
}
public AppComponent getAppComponent(){
return appComponent;
}
}
应用组件
@Component(modules = {AppModule.class,MainModule.class})
public interface AppComponent {
void inject(MainActivity activity);
void inject(LoginActivity activity);
}
主模块
@Module
public class MainModule {
@Provides
public MainContract.Model providesMainModel(){
return new MainModel();
}
@Provides
public LoginContract.Model providesLoginModel(){
return new LoginModel();
}
}
因为你的应用程序模块中有 Context
,你可以将 Context
作为参数添加到 LoginModel
构造函数。
@Provides
public LoginContract.Model providesLoginModel(Context contect){
return new LoginModel(contect);
}
@Provides
public LoginContract.Presenter providesLoginPresenter(LoginContract.Model model){
return new LoginPresenter(model);
}
但请记住,您必须仅在 Activity 和 Fragments 上使用 android
包以便于测试。所以你的做法是错误的。
编辑
对我来说,最好的选择是像这样为 SharedPreferences 创建 class
public class Preferences {
private final SharedPreferences preferences;
private String key;
private String defaultValue;
public StringPreferences(@NonNull SharedPreferences preferences) {
this.preferences = preferences;
}
@Nullable
public String get(String mykey) {
return preferences.getString(mykey, defaultValue);
}
public void set(@NonNull String mykey, @Nullable String value) {
preferences.edit().putString(mykey, value).apply();
}
// same way for integers, longs, doubles and booleans
public boolean isSet() {
return preferences.contains(key);
}
public void delete() {
preferences.edit().remove(key).apply();
}
}
然后在应用程序模块 I Provide
SharedPreferences
@Provides
@Singleton
public SharedPreferences provideSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
@Provides
@Singleton
public Preferences providePreferences(SharedPreferences prefs) {
return new Preferences(prefs);
}
终于在主模块中
@Provides
public LoginContract.Model providesLoginModel(Preferences prefs){
return new LoginModel(prefs);
}
@Provides
public LoginContract.Presenter providesLoginPresenter(LoginContract.Model model){
return new LoginPresenter(model);
}
我正在尝试使用 MVP 模式和用于依赖注入的 Dagger 2 重构我的应用程序。
我创建了提供应用程序上下文的模块,我想获取上下文以获取模型层上的SharedPreferences
。
我在 Presenter 层上注入了 Context,它与 SharedPreference
一起工作,但是当我移动到模型层时,Dagger 在 Context
变量上注入了一个 null
值。
注入
@Inject
public Context mContext;
应用模块
AppModule 提供应用上下文
@Module
public class AppModule {
private App app;
public AppModule(App app){
this.app = app;
}
@Provides
public Context providesApp(){
return app.getApplicationContext();
}
}
申请
public class App extends Application {
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.mainModule(new MainModule())
.build();
}
public AppComponent getAppComponent(){
return appComponent;
}
}
应用组件
@Component(modules = {AppModule.class,MainModule.class})
public interface AppComponent {
void inject(MainActivity activity);
void inject(LoginActivity activity);
}
主模块
@Module
public class MainModule {
@Provides
public MainContract.Model providesMainModel(){
return new MainModel();
}
@Provides
public LoginContract.Model providesLoginModel(){
return new LoginModel();
}
}
因为你的应用程序模块中有 Context
,你可以将 Context
作为参数添加到 LoginModel
构造函数。
@Provides
public LoginContract.Model providesLoginModel(Context contect){
return new LoginModel(contect);
}
@Provides
public LoginContract.Presenter providesLoginPresenter(LoginContract.Model model){
return new LoginPresenter(model);
}
但请记住,您必须仅在 Activity 和 Fragments 上使用 android
包以便于测试。所以你的做法是错误的。
编辑
对我来说,最好的选择是像这样为 SharedPreferences 创建 class
public class Preferences {
private final SharedPreferences preferences;
private String key;
private String defaultValue;
public StringPreferences(@NonNull SharedPreferences preferences) {
this.preferences = preferences;
}
@Nullable
public String get(String mykey) {
return preferences.getString(mykey, defaultValue);
}
public void set(@NonNull String mykey, @Nullable String value) {
preferences.edit().putString(mykey, value).apply();
}
// same way for integers, longs, doubles and booleans
public boolean isSet() {
return preferences.contains(key);
}
public void delete() {
preferences.edit().remove(key).apply();
}
}
然后在应用程序模块 I Provide
SharedPreferences
@Provides
@Singleton
public SharedPreferences provideSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
@Provides
@Singleton
public Preferences providePreferences(SharedPreferences prefs) {
return new Preferences(prefs);
}
终于在主模块中
@Provides
public LoginContract.Model providesLoginModel(Preferences prefs){
return new LoginModel(prefs);
}
@Provides
public LoginContract.Presenter providesLoginPresenter(LoginContract.Model model){
return new LoginPresenter(model);
}