Dagger 2 的单例 SharedPreferences

Singleton SharedPreferences with Dagger 2

我正在尝试使用 Dagger 2 创建 SharedPreferences 的单例,但我不断收到以下错误消息:

com.test.app.injection.component.ConfigPersistentComponent scoped with @com.test.app.injection.ConfigPersistent may not reference bindings with different scopes:
@Singleton class com.test.app.data.local.PreferencesHelper

我正在尝试通过 MainPresenter 中的注入构造函数访问共享首选项。使用 Singleton DataManager 进行 API 访问可以通过注入的构造函数正常工作,但不适用于 SharedPreferences。

这是我的设置:

AppModule

@Module(includes = {ApiModule.class})
public class AppModule {
    private final Application application;

    public AppModule(Application application) {
        this.application = application;
    }

    @Provides
    Application provideApplication() {
        return application;
    }

    @Provides
    @ApplicationContext
    Context provideContext() {
        return application;
    }

    @Provides
    @Singleton
    @ApplicationContext
    SharedPreferences provideSharedPreference(@ApplicationContext Context context) {
        return context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
    }
}

AppComponent

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    @ApplicationContext
    Context context();

    Application application();

    DataManager apiManager();

    @ApplicationContext
    SharedPreferences prefManager(Context context);
}

ConfigPersistentComponent

/**
 * A dagger component that will live during the lifecycle of an Activity or Fragment but it won't be
 * destroy during configuration changes. Check {@link BaseActivity} and {@link BaseFragment} to see
 * how this components survives configuration changes. Use the {@link ConfigPersistent} scope to
 * annotate dependencies that need to survive configuration changes (for example Presenters).
 */
@ConfigPersistent
@Component(dependencies = AppComponent.class)
public interface ConfigPersistentComponent {

    ActivityComponent activityComponent(ActivityModule activityModule);

    FragmentComponent fragmentComponent(FragmentModule fragmentModule);
}

ConfigPersistent

/**
 * A scoping annotation to permit dependencies conform to the life of the {@link
 * ConfigPersistentComponent}
 */
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ConfigPersistent {
}

首选项助手

@Singleton
public class PreferencesHelper {

    private final SharedPreferences preferences;

    @Inject
    PreferencesHelper(SharedPreferences sharedPreferences) {
        preferences = sharedPreferences;
    }

    public void putString(@Nonnull String key, @Nonnull String value) {
        preferences.edit().putString(key, value).apply();
    }

    public String getString(@Nonnull String key) {
        return preferences.getString(key, "");
    }

    public void putBoolean(@Nonnull String key, @Nonnull boolean value) {
        preferences.edit().putBoolean(key, value).apply();
    }

    public boolean getBoolean(@Nonnull String key) {
        return preferences.getBoolean(key, false);
    }

    public void putInt(@Nonnull String key, @Nonnull boolean value) {
        preferences.edit().putBoolean(key, value).apply();
    }

    public int getInt(@Nonnull String key) {
        return preferences.getInt(key, -1);
    }

    public void clear() {
        preferences.edit().clear().apply();
    }
}

主讲人

@ConfigPersistent
public class MainPresenter extends BasePresenter<MainMvpView> {

    private final PreferencesHelper preferencesHelper;
    private final DataManager dataManager;

    @Inject
    public MainPresenter(PreferencesHelper preferencesHelper, DataManager dataManager) {
        this.preferencesHelper = preferencesHelper;
        this.dataManager = dataManager;
    }
...
}
@Provides
@Singleton
// @ApplicationContext // <-- remove this
SharedPreferences provideSharedPreference(@ApplicationContext Context context) {
    return context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
}

并添加:

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {    
    ...


    // @ApplicationContext
    SharedPreferences prefManager();

    PreferencesHelper preferencesHelper();
}