Open In App

Dagger 2 Android Example using Retrofit

Last Updated : 21 Dec, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

Dagger 2 Android implementation is easier and it is based on Dependency Injection Architecture. Dependency Injection is a design pattern, which is a concept of Object-Oriented Programming, where we don’t create an object of another class inside a class using the new keyword (for Java). Instead, we supply the needed object from the outside. It is a fully static, compile-time dependency injection framework for both Java and Android. It is an adaptation of an earlier version created by Square and now maintained by Google. Note that we are going to implement this project using the Java language. 

The Theoretical Part About Dagger 2

  • Dependency Provider: Dependencies are the objects that we need to instantiate inside a class. We cannot instantiate a class inside a class. The person who will provide us the objects that are called dependencies is called Dependency Provider. dagger2 is the class that you want to make a Dependency Provider, It needs to annotate it with the @Module annotation.
  • Dependency Consumer: Dependency consumer is a class where we need to instantiate the objects. Dagger will provide the dependency, and for this, we just need to annotate the object declaration with @Inject.
  • Component: The connection between our dependency provider and dependency consumer is provided via an interface by annotating it with @Component. And the rest of the thing will be done by Dagger.

Example

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.

Step 2: Before going to the coding section first you have to do some pre-task

Before going to the coding section first you have to do some pre-task. Go to the app > res > values > colors.xml section and set the colors for your app.

XML




<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#0F9D58</color>
    <color name="colorPrimaryDark">#0F9D58</color>
    <color name="colorAccent">#FF4081</color>
</resources>


Go to the Gradle Scripts > build.gradle (Module: app) section and import the following dependencies and click the “Sync Now” on the above pop up.

// these two lines are added for retrofit

implementation ‘com.squareup.retrofit2:retrofit:2.7.2’

implementation ‘com.squareup.retrofit2:converter-gson:2.7.2’

// these two lines are added for dagger

implementation ‘com.google.dagger:dagger:2.13’

annotationProcessor ‘com.google.dagger:dagger-compiler:2.13’

Go to the app > manifests > AndroidManifests.xml section and allow “Internet Permission“. Below is the code for the AndroidManifests.xml file.

<!– the internet permission , then only api calls can be retrieved –>

<uses-permission android:name=”android.permission.INTERNET” />

Step 3: Designing the UI

Below is the code for the activity_main.xml file. This will be under the app > src > main > res > layout folder. Depends upon different resolutions, sometimes we may need to have it under layout > hdpi or layout > xhdpi folders, etc.

XML




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <ListView
        android:id="@+id/listViewCountries"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark"/>
  
</RelativeLayout>


Step 4: Working with the Java file

App Module.java file:

In Retrofit(Retrofit is a REST Client for Java and Android), we need the context object. To supply the objects, so here we will create this module that will give us the Context.

Java




import android.app.Application;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
  
@Module
class AppModule {
    private Application mApplication;
  
    AppModule(Application mApplication) {
        this.mApplication = mApplication;
    }
  
    @Provides
    @Singleton
    Application provideApplication() {
        return mApplication;
    }
}


With the dagger, we need to annotate @Singleton when we want a single instance only.

API Module.java:

For Retrofit, we need a bunch of things. Cache, Gson, OkHttpClient, and the Retrofit itself. So we will define the providers for these objects here in this module.

  • Gson: It is a Java library that can be used to convert Java Objects into their JSON representation.
  • Okhttp: works with Retrofit, which is a brilliant API for REST.

Java




import android.app.Application;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
  
@Module
class ApiModule {
  
    String mBaseUrl;
  
    ApiModule(String mBaseUrl) {
        this.mBaseUrl = mBaseUrl;
    }
  
  
    @Provides
    @Singleton
    Cache provideHttpCache(Application application) {
        int cacheSize = 10 * 1024 * 1024;
        Cache cache = new Cache(application.getCacheDir(), cacheSize);
        return cache;
    }
  
    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gsonBuilder.create();
    }
  
    @Provides
    @Singleton
    OkHttpClient provideOkhttpClient(Cache cache) {
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.cache(cache);
        return client.build();
    }
  
    @Provides
    @Singleton
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(mBaseUrl)
                .client(okHttpClient)
                .build();
    }
}


Building Component: ApiComponent.java

Java




import javax.inject.Singleton;
import dagger.Component;
  
@Singleton
@Component(modules = {AppModule.class, ApiModule.class})
public interface ApiComponent {
    void inject(MainActivity activity);
}


We will inject in the MainActivity. We also define all the modules using the @Component annotation as we can see in the code.

MyApplication.java file:

Java




import android.app.Application;
  
public class MyApplication extends Application {
  
    private ApiComponent mApiComponent;
  
    @Override
    public void onCreate() {
        super.onCreate();
        // https://restcountries.eu/rest/v2/all -> It will list all the country details
        mApiComponent = DaggerApiComponent.builder()
                .appModule(new AppModule(this))
                .apiModule(new ApiModule("https://restcountries.eu/rest/v2/"))
                .build();
    }
  
    public ApiComponent getNetComponent() {
        return mApiComponent;
    }
}


MainActivity.java file:

Java




import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.List;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
  
public class MainActivity extends AppCompatActivity {
  
    // injecting retrofit
    @Inject Retrofit retrofit;
    ListView listView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          
          // injecting here
        ((MyApplication) getApplication()).getNetComponent().inject(this);
        listView = (ListView) findViewById(R.id.listViewCountries);
        getCountries();
    }
  
    private void getCountries() {
        Api api = retrofit.create(Api.class);
          
          // Call<List<Country>> call = RetrofitClient.getInstance().getMyApi().getCountries();
        Call<List<Country>> call = api.getCountries();
        call.enqueue(new Callback<List<Country>>() {
            @Override
            public void onResponse(Call<List<Country>> call, Response<List<Country>> response) {
                List<Country> countryList = response.body();
  
                // Creating an String array for the ListView
                String[] countries = new String[countryList.size()];
  
                // looping through all the countries and inserting 
                  // the names inside the string array
                for (int i = 0; i < countryList.size(); i++) {
                    countries[i] = countryList.get(i).getName();
                }
  
                // displaying the string array into listview
                listView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, countries));
            }
  
            @Override
            public void onFailure(Call<List<Country>> call, Throwable t) {
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}


Output:

Example Request:

https://restcountries.eu/rest/v2/all will provide the output as shown in the image. We will take the country name from that

Example Response:

The output of the above REST API URL

As we are taking country names only we will get as a list like Afghanistan,…..India etc., On executing the above code, we can able to get the output as shown below.

You can find the source code: https://github.com/raj123raj/dagger-retrofit



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads