Android MVP + Dagger2 + Retrofit + RxJava

Filed Under: Android

In this tutorial, we’ll be developing an application using MVP, Dagger2, Retrofit and RxJava.

These days cryptocurrency is the latest fad. So we’ll be creating a cryptocurrency application using the above things.

Overview

To proceed further you must have an overview of the Model View Presenter, Dependency Injection, Retrofit and RxJava libraries.
We have covered them individually and in combination with the following tutorial links specified:

If you know the basics of the above things, the following example should be an easy ride. Let’s dive right in!

Create a new Android Studio project.

Libaries

Add the following libraries in your app’s build.gradle file.
android mvp dagger2 retrofit rxjava libraries

RxAndroid is just like RxJava. It contains the schedulers and threads for the Android framework.

Project Structure

android mvp dagger2 retrofit rxjava project structure

The di package contains the dependency injection – Dagger2 related files. The mvp package consists of the MVP related ones and so on.

Where and how do we start?
It can get confusing when we are asked to use so many different things in our project.

The beginning is always tricky. Once we know the process, everything becomes easy.

So let’s list down our requirements and how we’ll approach them.

Our application would contain a single activity. It would host a RecyclerView to display the data from the API call. For the API call we’ll use Retrofit and RxJava.

Approach:

  • Create your activity and recyclerview xml layouts first. Lock the Design before you code.
  • Create the APIInterface.java class. It defines the API calls to be made.
  • Create the POJO data class which would parse the response from the API call.
  • Start by creating the Interface for the MVP – MainActivityContract.java.
  • Create the di modules, components, scopes and qualifiers.
  • Now create the PresenterImpl.
  • Finally, write the MainActivity and RecyclerViewAdapter classes plugging the Dependencies and the MVP pattern in.

Layout code

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

recycler_view_list_row.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/txtCoin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/txtCurrentPrice"
        app:layout_constraintTop_toTopOf="parent"
         />

    <TextView
        android:id="@+id/txtCurrentPrice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtCoin"
        />


    <TextView
        android:id="@+id/txtOneHourChange"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/txtOneHour"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="1H"
        app:layout_constraintEnd_toStartOf="@+id/txtOneHourChange"
        app:layout_constraintTop_toTopOf="@+id/txtOneHourChange" />


    <TextView
        android:id="@+id/txt24HourChange"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtOneHourChange" />

    <TextView
        android:id="@+id/txt7Day"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="7D"
        app:layout_constraintEnd_toStartOf="@+id/txt7DayChange"
        app:layout_constraintTop_toTopOf="@+id/txt7DayChange" />


    <TextView
        android:id="@+id/txt24Hour"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="24H"
        app:layout_constraintBottom_toTopOf="@+id/txt7DayChange"
        app:layout_constraintEnd_toStartOf="@+id/txt24HourChange"
        app:layout_constraintTop_toTopOf="@+id/txt24HourChange" />

    <TextView
        android:id="@+id/txt7DayChange"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txt24HourChange" />

</android.support.constraint.ConstraintLayout>

APIInterface.java


package com.journaldev.mvpdagger2retroiftrxjava.retrofit;

import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.List;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;

public interface APIInterface {

    @GET("ticker/?")
    Observable<List<CryptoData>> getData(@Query("limit") String limit);
}

The base URL would be defined in our RetrofitModule.
We’re using this API.

CryptoData.java


package com.journaldev.mvpdagger2retroiftrxjava.pojo;

import com.google.gson.annotations.SerializedName;

public class CryptoData {

    @SerializedName("id")
    public String id;
    @SerializedName("name")
    public String name;
    @SerializedName("symbol")
    public String symbol;
    @SerializedName("rank")
    public String rank;
    @SerializedName("price_usd")
    public String priceUsd;
    @SerializedName("price_btc")
    public String priceBtc;
    @SerializedName("24h_volume_usd")
    public String _24hVolumeUsd;
    @SerializedName("market_cap_usd")
    public String marketCapUsd;
    @SerializedName("available_supply")
    public String availableSupply;
    @SerializedName("total_supply")
    public String totalSupply;
    @SerializedName("percent_change_1h")
    public String percentChange1h;
    @SerializedName("percent_change_24h")
    public String percentChange24h;
    @SerializedName("percent_change_7d")
    public String percentChange7d;
    @SerializedName("last_updated")
    public String lastUpdated;
    
}

MainActivityContract.java
This is the blueprint of our View-Model-Presenter:


package com.journaldev.mvpdagger2retroiftrxjava.mvp;

import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.List;

public interface MainActivityContract {
    interface View {
        void showData(List<CryptoData> data);
        void showError(String message);
        void showComplete();
        void showProgress();
        void hideProgress();
    }

    interface Presenter {
        void loadData();
    }
}

ActivityScope.java


package com.journaldev.mvpdagger2retroiftrxjava.di.scopes;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;

@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ActivityScope {
}

ApplicationScope.java


package com.journaldev.mvpdagger2retroiftrxjava.di.scopes;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;

@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ApplicationScope {
}

ActivityContext.java


package com.journaldev.mvpdagger2retroiftrxjava.di.qualifier;

import javax.inject.Qualifier;

@Qualifier
public @interface ActivityContext {

}

ApplicationContext.java


package com.journaldev.mvpdagger2retroiftrxjava.di.qualifier;

import javax.inject.Qualifier;


@Qualifier
public @interface ApplicationContext {

}

ContextModule.java


package com.journaldev.mvpdagger2retroiftrxjava.di.module;

import android.content.Context;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import dagger.Module;
import dagger.Provides;

@Module
public class ContextModule {
    private Context context;

    public ContextModule(Context context) {
        this.context = context;
    }

    @Provides
    @ApplicationScope
    @ApplicationContext
    public Context provideContext() {
        return context;
    }
}

MainActivityContextModule.java


package com.journaldev.mvpdagger2retroiftrxjava.di.module;

import android.content.Context;


import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;

import dagger.Module;
import dagger.Provides;

@Module
public class MainActivityContextModule {
    private MainActivity mainActivity;

    public Context context;

    public MainActivityContextModule(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
        context = mainActivity;
    }

    @Provides
    @ActivityScope
    public MainActivity providesMainActivity() {
        return mainActivity;
    }

    @Provides
    @ActivityScope
    @ActivityContext
    public Context provideContext() {
        return context;
    }

}

RetrofitModule.java


package com.journaldev.mvpdagger2retroiftrxjava.di.module;


import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

@Module
public class RetrofitModule {

    @Provides
    @ApplicationScope
    APIInterface getApiInterface(Retrofit retroFit) {
        return retroFit.create(APIInterface.class);
    }

    @Provides
    @ApplicationScope
    Retrofit getRetrofit(OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .baseUrl("https://api.coinmarketcap.com/v1/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    @Provides
    @ApplicationScope
    OkHttpClient getOkHttpCleint(HttpLoggingInterceptor httpLoggingInterceptor) {
        return new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .build();
    }

    @Provides
    @ApplicationScope
    HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return httpLoggingInterceptor;
    }
}

MainActivityMvpModule.java


package com.journaldev.mvpdagger2retroiftrxjava.di.module;

import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.MainActivityContract;
import dagger.Module;
import dagger.Provides;

@Module
public class MainActivityMvpModule {
    private final MainActivityContract.View mView;


    public MainActivityMvpModule(MainActivityContract.View mView) {
        this.mView = mView;
    }

    @Provides
    @ActivityScope
    MainActivityContract.View provideView() {
        return mView;
    }


}

AdapterModule.java


package com.journaldev.mvpdagger2retroiftrxjava.di.module;

import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.RecyclerViewAdapter;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;

import dagger.Module;
import dagger.Provides;

@Module(includes = {MainActivityContextModule.class})
public class AdapterModule {

    @Provides
    @ActivityScope
    public RecyclerViewAdapter getCoinList(RecyclerViewAdapter.ClickListener clickListener) {
        return new RecyclerViewAdapter(clickListener);
    }

    @Provides
    @ActivityScope
    public RecyclerViewAdapter.ClickListener getClickListener(MainActivity mainActivity) {
        return mainActivity;
    }
}

Components are what inject the dependencies from the Modules.

ApplicationComponent.java


package com.journaldev.mvpdagger2retroiftrxjava.di.component;

import android.content.Context;


import com.journaldev.mvpdagger2retroiftrxjava.MyApplication;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.ContextModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.RetrofitModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;

import dagger.Component;

@ApplicationScope
@Component(modules = {ContextModule.class, RetrofitModule.class})
public interface ApplicationComponent {

    APIInterface getApiInterface();

    @ApplicationContext
    Context getContext();
    
    void injectApplication(MyApplication myApplication);
}

MainActivityComponent.java


package com.journaldev.mvpdagger2retroiftrxjava.di.component;

import android.content.Context;

import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.AdapterModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityMvpModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import dagger.Component;


@ActivityScope
@Component(modules = {AdapterModule.class, MainActivityMvpModule.class}, dependencies = ApplicationComponent.class)
public interface MainActivityComponent {

    @ActivityContext
    Context getContext();
    void injectMainActivity(MainActivity mainActivity);
}

PresenterImpl.java


package com.journaldev.mvpdagger2retroiftrxjava.mvp;

import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;
import java.util.List;
import javax.inject.Inject;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class PresenterImpl implements MainActivityContract.Presenter {

    APIInterface apiInterface;
    MainActivityContract.View mView;

    @Inject
    public PresenterImpl(APIInterface apiInterface, MainActivityContract.View mView) {
        this.apiInterface = apiInterface;
        this.mView = mView;
    }

    @Override
    public void loadData() {

        mView.showProgress();

        apiInterface.getData("10").subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<CryptoData>>() {
                    @Override
                    public void onCompleted() {
                        mView.showComplete();
                        mView.hideProgress();
                    }

                    @Override
                    public void onError(Throwable e) {
                        mView.showError("Error occurred");
                        mView.hideProgress();
                    }

                    @Override
                    public void onNext(List<CryptoData> data) {
                        mView.showData(data);
                    }
                });
    }
}

@Inject on the constructor says that this class’s object would be injected in the MainActivity.
The Presenter invokes the required View interface’s methods that’ll trigger the actions in the MainActivity.

MyApplication.java


package com.journaldev.mvpdagger2retroiftrxjava;

import android.app.Activity;
import android.app.Application;

import com.journaldev.mvpdagger2retroiftrxjava.di.component.ApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.DaggerApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.ContextModule;


public class MyApplication extends Application {

    ApplicationComponent applicationComponent;

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

        applicationComponent = DaggerApplicationComponent.builder().contextModule(new ContextModule(this)).build();
        applicationComponent.injectApplication(this);

    }

    public static MyApplication get(Activity activity){
        return (MyApplication) activity.getApplication();
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }
}

MainActivity.java


package com.journaldev.mvpdagger2retroiftrxjava;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.journaldev.mvpdagger2retroiftrxjava.di.component.ApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.DaggerMainActivityComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.MainActivityComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityContextModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityMvpModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.MainActivityContract;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.PresenterImpl;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;

import java.util.List;

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity implements MainActivityContract.View, RecyclerViewAdapter.ClickListener {

    private RecyclerView recyclerView;
    private ProgressBar progressBar;
    MainActivityComponent mainActivityComponent;

    @Inject
    public RecyclerViewAdapter recyclerViewAdapter;

    @Inject
    @ApplicationContext
    public Context mContext;

    @Inject
    @ActivityContext
    public Context activityContext;

    @Inject
    PresenterImpl presenter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        ApplicationComponent applicationComponent = MyApplication.get(this).getApplicationComponent();
        mainActivityComponent = DaggerMainActivityComponent.builder()
                .mainActivityContextModule(new MainActivityContextModule(this))
                .mainActivityMvpModule(new MainActivityMvpModule(this))
                .applicationComponent(applicationComponent)
                .build();

        mainActivityComponent.injectMainActivity(this);

        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(activityContext));
        recyclerView.setAdapter(recyclerViewAdapter);
        progressBar = findViewById(R.id.progressBar);

        presenter.loadData();


    }

    @Override
    public void launchIntent(String name) {
        Toast.makeText(mContext, name, Toast.LENGTH_SHORT).show();
        // startActivity(new Intent(activityContext, DetailActivity.class).putExtra("name", name));
    }

    @Override
    public void showData(List<CryptoData> data) {
        recyclerViewAdapter.setData(data);
    }

    @Override
    public void showError(String message) {
        Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showComplete() {

    }

    @Override
    public void showProgress() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        progressBar.setVisibility(View.GONE);
    }
}

Thanks to DI and MVP, we’ve injected everything and separated the network calls from the MainActivity.
The MainActivity.java only populates the views as per the instructions from the Presenter.

The code for the RecyclerViewAdapter.java class is given below:


package com.journaldev.mvpdagger2retroiftrxjava;

import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    private List<CryptoData> data;
    private RecyclerViewAdapter.ClickListener clickListener;

    @Inject
    public RecyclerViewAdapter(ClickListener clickListener) {
        this.clickListener = clickListener;
        data = new ArrayList<>();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_row, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.txtCoin.setText(data.get(position).symbol);
        holder.txtCurrentPrice.setText(data.get(position).priceUsd);
        holder.txt1HourChange.setText(data.get(position).percentChange1h + "%");
        holder.txt24HourChange.setText(data.get(position).percentChange24h + "%");
        holder.txt7DayChange.setText(data.get(position).percentChange7d + "%");

    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private TextView txtCoin;
        private TextView txtCurrentPrice;
        private TextView txt1HourChange;
        private TextView txt24HourChange;
        private TextView txt7DayChange;
        private ConstraintLayout constraintLayoutContainer;

        ViewHolder(View itemView) {
            super(itemView);

            txtCoin = itemView.findViewById(R.id.txtCoin);
            txtCurrentPrice = itemView.findViewById(R.id.txtCurrentPrice);
            txt1HourChange = itemView.findViewById(R.id.txtOneHourChange);
            txt24HourChange = itemView.findViewById(R.id.txt24HourChange);
            txt7DayChange = itemView.findViewById(R.id.txt7DayChange);
            constraintLayoutContainer = itemView.findViewById(R.id.constraintLayout);

            constraintLayoutContainer.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    clickListener.launchIntent(data.get(getAdapterPosition()).name);
                }
            });
        }
    }

    public interface ClickListener {
        void launchIntent(String name);
    }

    public void setData(List<CryptoData> data) {
        this.data.addAll(data);
        notifyDataSetChanged();
    }
}


REBUILD the Project to create the Dagger files automatically.

The output of the above application in action is given below:
android-mvp-dagger2-retrofit-rxjava

This brings an end to this hands-on tutorial in which we’ve used MVP, Dagger2, Retrofit, RxJava along with a RecyclerView. You can download the project from the link below.

Comments

  1. ameen says:

    Please explain the use of this application, i didn’t understand why to build this.

  2. mahesh says:

    DaggerMainActivityComponent not find . getting error

    1. Anupam says:

      rebuild your project

  3. osanfer says:

    In first place thanks for the tutorial, it’s really good. I have a couple of questions.

    Would it make much difference if we used javarx2?

    And

    Could you add some example tests?

    thanks a lot!

  4. glori says:

    HELP!
    I am successfully generating DaggerMainActivityComponent however I cannot call builder on it? FYI I have turned on annotation processing and I have compared all my code. Also, this was not mentioned but under my manifest file I did add a line under application to point to MyApplication.

    Any pointers or explanation of why this error is coming up is greatly appreciated.

    thank you

  5. Ashik says:

    Thanks a lote.
    Its working proprly,Can u describe all class.

  6. dev.jr says:

    It’s a really good tutorial. Thanks to this tutorial I was able to understand dagger and rxjava

  7. Parimala says:

    Hi, could you please tell me how to handle json object response with this code as it expecting json array i am getting following error
    Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

    I am new to RxJava and Retrofit concepts and this tutorial is a great help

  8. Hiren says:

    Nice article that cover major things like MVP, dagger2, retrofit and RxJava all together. Also like the Approach that guide how to start. However in case of multiple module/feature in the project, can you please describe how the project structure looks like?

  9. thriveni says:

    getting error : android.app.Application cannot be provided without an @Inject constructor or from an @Provides-annotated method.

    tried the solution from stackoverflow. nothing worked.

  10. alok says:

    DaggerApplicationComponent is not working.

    1. Anupam says:

      Clean and Rebuild the project.
      Make sure you have added all the appropriate dependencies.

  11. Shyam says:

    I am new to develop android dagger application, I am trying to solve this application but it gave me error as

    Error:(17, 53) error: cannot find symbol class DaggerMainActivityComponent

    in your project app file, same error will occur

    1. Anupam says:

      Try cleaning and rebuilding your project.

      1. alok says:

        not working

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages