【问题标题】:Wrapping SharedPreferences with Dagger 2 and RxJava2用 Dagger 2 和 RxJava2 包装 SharedPreferences
【发布时间】:2017-09-25 08:53:00
【问题描述】:

我是否需要封装 Android SharedPreferences 类?如果是的话,你能给我一个简单的工作例子吗?

我知道如何使用 SharedPreferences,但是在包装它并为其提供 Dagger 2 和 RxJava2 时,我感到很困惑。

【问题讨论】:

    标签: android sharedpreferences dagger-2 rx-java2


    【解决方案1】:

    我通常只是使用名为LocalStorage 或类似的接口来包装它。然后将Context 注入实现并像往常一样实现您的 SharedPreferences。如果您想使用 Rx,只需确保您的接口方法返回 Observables

    然后,当您需要使用 SharedPeferences 时,只需注入 LocalStorage 即可。

    编辑:我不确定您需要多少代码,但这里有一个示例。

    从定义接口开始

    public interface LocalStorage {
        void writeMessage(String message);
        Observable<String> readMessage();
    }
    

    然后使用 SharedPreferences 编写此接口的实现。那么我们需要什么才能让它发挥作用呢?好吧,我们真正需要的是一个Context,但我们不用担心,当我们在dagger 2 模块中创建LoginStorage 时,我们将通过构造函数传递一个。

    public class SharedPrefStorage implements LocalStorage {
    
        private Context context;
    
        public SharedPrefStorage(Context context) {
            this.context = context;
        }
    
        @Override
        public void writeMessage(String message) {
            context.getSharedPreferences("sharedprefs", Context.MODE_PRIVATE)
                    .edit().putString("myMessage", message).apply();
        }
    
        @Override
        public Observable<String> readMessage() {
            return Observable.fromCallable(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return context.getSharedPreferences("sharedprefs", Context.MODE_PRIVATE)
                        .getString("myMessage", "");
                }
            }
        });
    }
    

    如您所见,我们只是像往常一样读取和写入值,没什么特别的。现在我们只需将它添加到我们的 Dagger 2 AppModule(或您决定调用它的任何名称)。我们已经知道,SharedPrefStorage 需要一个 Context 才能工作,因此将其作为参数,dagger 将注入它(前提是您有一个带有上下文的 @Provides 方法,例如您的应用程序类)。

    @Module
    public class AppModule {
    
        private MyApplication app;
    
        public AppModule(MyApplication app) {
            this.app = app;
        }
    
        @Provides
        @Singleton
        public MyApplication provideApp() {
            return app;
        }
    
        @Provides
        @Singleton
        public LocalStorage provideLocalStorage(MyApplication context)
            return new SharedPrefStorage(context);
        }
    }
    

    然后,当然,让我们将它添加到 Dagger 2 组件中,这样我们就可以真正公开 LocalStorage 并可以将它注入到我们想要的任何地方。

    @Singleton
    @Component(modules = AppModule.class)
    public interface AppComponent {
        LocalStorage localStorage();
    }
    

    现在我们可以在需要时注入 LocalStorage。我希望这能解决问题。

    【讨论】:

    • 你能给它一个原始样本吗?
    • 顺便说一句,你的标题有错字。您可能需要更改它,以便有相同问题的人可以找到此线程。
    • 我很好奇在这里使用接口 LocalStorage 是否有任何好处,因为它只有一个实现?
    • 如果将来您必须更改实现以使用 SQL 数据库,那么重构的痛苦将大大减少,因为您只需实现接口并注入新的实现即可。 LocalStorage 的每次使用都可以保持不变,并且工作方式相同。但是不,理论上你不必使用界面
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 2020-02-25
    • 1970-01-01
    • 2018-04-09
    • 2017-03-22
    相关资源
    最近更新 更多