Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping SharedPreferences with Dagger 2 and RxJava2

Do I need to wrap the Android SharedPreferences class or not? If yes, can you please provide me a simple working example?

I know how to use the SharedPreferences, but when it comes to wrapping it and providing it with Dagger 2 and RxJava2 I am confused.

like image 927
Avian Driyanto Avatar asked Sep 12 '25 07:09

Avian Driyanto


1 Answers

I usually just wrap it using an interface called LocalStorage or something similar. Then inject a Context into the implementation and implement your SharedPreferences as usual. If you want to use Rx just make sure your interface methods return Observables.

Then whenever you need to use SharedPeferences just have a LocalStorage injected and you're all set.

Edit: Im not sure how much code you need but here's a sample.

Start off by defining an interface

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

Then write the implementation of this interface using SharedPreferences. So what do we need for this to work? Well, all we really need is a Context, but let's not worry about that, we will pass one through the constructor when we create the LoginStorage in the dagger 2 module.

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

As you see we simply read and write the values as usual, nothing fancy. Now we just add this to our Dagger 2 AppModule (or whatever you decided to call it). We already know that we will need a Context for the SharedPrefStorage to work, so put it as a parameter and dagger will inject it (provided you have a @Provides method with a context, for example your application class).

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

And then, of course, let's add it to our Dagger 2 component so that we actually expose the LocalStorage and can have it injected wherever we want it.

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

Now we can just have our LocalStorage injected whenever we need one. I hope this clears things up.

like image 66
JesperQv Avatar answered Sep 14 '25 00:09

JesperQv