How to use Rxjava with Dagger2 and Retrofit and OkHttp and Gson

How to use Rxjava with Dagger2 and Retrofit and OkHttp and Gson

In this article we will see how to create a complete project using rxjava, dagger2, retrofit, okhttp and Gson

Click here to Download or look at Source code of this example from github

First let's illustrate basic structure of each library

Dagger2

To use dagger you must consider that there are three component must implemented

  1. Module (or more): this is classes which will provide objects
  2. Component (or more): this is interface link between providers and injectable objects (classes which consume object that module provides)
  3. Injectable object (Usually Activity, but it could be any thing else)

Those points will be clear enough at implementation part.

Rxjava 

RxJava also consist of 3 components

  1. Observable : Object with heavy process (like http request and response)
  2. Scheduler: specify in which process will observable execute its process and in which process results will given
  3. Subscriber: object will receive results from observable after finishing it's job.

Retrofit

you can take a look at this article https://www.garudax.id/pulse/retrofit-rxjava-eslam-ahmad, to see how to use retrofit

OkHTTP and Gson: Just builders will used in this article


Example Structure

We need to inject Retrofit object to our main activity class, also Retrofit object need some other dependencies like

  • Base Url
  • Gson converter object
  • HTTP object

Http object also need dependencies like Application object to add cache.

So i will create 2 Modules, one will provide retrofit and http and gson, i will name it NetModule, and one to provide application and i will name it ApplicationModule.

As i mentioned (in dagger structure) we need Component interface i will name it NetComponent

Then Retrofit need

  1. Api interface that will handle http requests, in this example i will name it RestApi
  2. POJO classes for single item (in this example it will be only one class it's name will be Post)

And for Android we need:

  1. Application Class which will handle component initialization, i will name it App
  2. Activity, i will name it MainActivity

Let's start implementing our project

After creating a new project you will need to add necessary dependency

//RxJava
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.1.7'
// Retrofit
compile 'com.squareup.retrofit2:retrofit:2.3.0'
//RxJava and Retrofit integrantion
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

// gson
compile 'com.google.code.gson:gson:2.8.0'
//gson and retrofit integration
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

//dagger
compile 'com.google.dagger:dagger:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
//OkHttp
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.7.0'


1- Create NetModule (Which will provide Retrofit, OkHttp, Gson).

@Module
public class NetModule {

    private String baseUrl;

    public NetModule(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    @Provides OkHttpClient provideHttpClient(Cache cache){
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.cache(cache);
        return client.build();
    }

    @Provides Cache provideCache(Application application){
        int cacheSize = 1024*1024*10;
        return new Cache(application.getCacheDir(),cacheSize);
    }
    @Provides Gson provideGson(){
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gsonBuilder.create();
    }

    @Provides Retrofit provideRetrofit(Gson gson,OkHttpClient client){
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(baseUrl)
                .build();
    }
}

Because it is a module it will inject all methods params if it available!

If you looked to provideRetrofit method it need Gson object and OkHttpClient object as parameters and there are two methods provide those items so Dagger will inject it automatically.

But there are function named provideCache need Application object which not exist in this class

so let's create ApplicationModule class

@Module
public class ApplicationModule {

    private Application application;

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

    @Provides Application provideApplication(){
        return application;
    }
}

When we link those Modules provideCache will take it's dependencies by default.

Lets make the interface that will link modules with injectable object.

@Component (modules = {ApplicationModule.class,NetModule.class})
public interface NetComponent {
    void injectMainActivity(MainActivity mainActivity);
}

This interface will make link between Application module and NetModule, and will make MainActivity injectable.

Then we must build Dagger object so from build menu click make project after finishing

create a new class named App extends Application class

public class App extends Application {

    NetComponent netComponent;
    @Override
    public void onCreate() {
        super.onCreate();

        netComponent = DaggerNetComponent.builder()
                .applicationModule(new ApplicationModule(this))
                .netModule(new NetModule("https://jsonplaceholder.typicode.com/"))
                .build();
    }

    public NetComponent getNetComponent(){
        return netComponent;
    }
}

Please note that "https://jsonplaceholder.typicode.com/" is the api base url.

then you must add App class to manifest file

<application android:name=".App"

and at MainActivity class you can add this line

((App) getApplication()).getNetComponent().injectMainActivity(this);

At this point Dagger is implemented and ready to do it's job.

Let's finish this by create Retrofit classes (POJO and Interface)

POJO object

public class Post {
    private String title;
    private String body;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

Interface

public interface RestApi {
    @GET("/posts")
    Observable<List<Post>> getPosts();
}

Here we go, Every thing is ready let's test our work

public class MainActivity extends AppCompatActivity {

    @Inject Retrofit retrofit;//Auto Inject Retrofit from NetModule
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((App) getApplication()).getNetComponent().injectMainActivity(this); //Link Main activity with modules through component
        Observable<List<Post>> call = retrofit.create(RestApi.class).getPosts();//get observable posts list from api

        //Observer which will take result from observable object
        Observer<List<Post>> observer = new Observer<List<Post>>() {
            @Override
            public void onSubscribe(Disposable d) {
            }

            @Override
            public void onNext(List<Post> posts) {
                for(Post post : posts){
                    Log.i("TEST",post.getTitle()); //Write post title at log
                }
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onComplete() {
            }
        };

        call.subscribeOn(Schedulers.io())//run http get request at io Thread
                .observeOn(AndroidSchedulers.mainThread()) //get result at main Thread
                .subscribe(observer);//Fire observable


    }
}

Click here to Download or look at Source code of this example from github

Thank you so much Eslam. I was having a lot of trouble trying to understand how to use Dagger 2 with RxJava. It´s all clear now, thanks to you and your good will to teach others. Have a good day.

Like
Reply

Why you set provideHttpClient @Reusable in NetModule

Like
Reply

To view or add a comment, sign in

More articles by Eslam Ahmad

  • Kotlin Android / KMP Benchmarking

    We all love the social media videos, specially the short videos (it's funny), we may have some work and deliverables to…

  • How KMM can enhance business analytics numbers

    Please Feel free to add a comment to correct me, recommend an edit, and if you do like it, clap and share 🫶😅…

  • Unit Tests - Basics - Part 1

    In this series of articles i need to take chance to share my knowledge in unit testing with you, also it will great if…

    11 Comments
  • Koin - Light, simple Kotlin DI Framework

    As i mentioned in previous article, i will write articles to try to illustrate how to use koin in your code, to avoid…

    1 Comment
  • Stop using dagger

    Dagger is a dependency injection library, used to create testable code. But you payoff time and headache to make your…

    2 Comments
  • Retrofit and RxJava

    What is Retrofit? Simply if you need to send or receive data from server you need to serialize data to be able to…

    8 Comments

Others also viewed

Explore content categories