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