Dao is null while using Dagger2

Viewed 40

When i call DAO in presenter, it returns null and causes NPE. Some code here: DAO class

@Dao
public interface ElementsDao {
    @Query("SELECT * FROM   `elements`")
    Flowable<List<Elements>> getAll();

    @Insert
    Maybe<Long> insert(Elements element);...
}

modules classes:

@Module
public class DatabaseModule {

    private AppDatabase appDatabase;
    public DatabaseModule(Application mApplication){
        appDatabase = Room.databaseBuilder(mApplication, AppDatabase.class,"dbWarehouse")
                .setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
                .build();
    }

    @Singleton
    @Provides
    public AppDatabase provideDatabase(){
        return appDatabase;
    }

    @Singleton
    @Provides
    ElementsDao providesElementsDao(AppDatabase appDatabase){
        return appDatabase.getElementsDao();
    }
}

@Module
public class AppModule {
    Application mApplication;

    public AppModule(Application application){
        mApplication = application;
    }

    @Provides
    @Singleton
    Application providesApplication() {
        return mApplication;
    }
}

Component class

@Singleton
@Component(dependencies = {},modules = {AppModule.class, DatabaseModule.class})
public interface AppComponent {

    void inject(MainActivity mainActivity);
    void inject(ElementsActivity elementsActivity);
    void inject(ActivityElementsPresenter activityElementsPresenter);

    ElementsDao elementsDao();

    AppDatabase appDatabase();

    Application application();
}

App class (declared in manifest)

public class App extends Application {
    private static AppComponent appComponent;
    @Override
    public void onCreate() {
        super.onCreate();
        initDagger();
    }
    private void initDagger(){
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .databaseModule(new DatabaseModule(this))
                .build();
    }

    public static AppComponent getAppComponent() {
        return appComponent;
    }
}

And presenter

@InjectViewState
public class ActivityElementsPresenter extends MvpPresenter<ActivityElementsView> {
    @Inject
    ElementsDao elementsDao;

    public void addElement(Elements element){
        elementsDao.insert(element).subscribeOn(Schedulers.io())...

UPDATE AppDatabase class

@Database(entities = {Elements.class}, version = 1, exportSchema = false)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
    public abstract ElementsDao getElementsDao();
    //...
}

While debuging i setted a point in presenter and saw that dao isn't initialized elementsDao Trying to use something like App.getAppComponent().elementsDao(); but it inst works too.

1 Answers

You need to do it this way,

@InjectViewState
public class ActivityElementsPresenter extends MvpPresenter<ActivityElementsView> {
    @Inject
    ElementsDao elementsDao;

    public ActivityElementsPresenter(){
       App.getAppComponent().inject(this);//calling the dagger's injector to inject dependency.
    }

    public void addElement(Elements element){
        elementsDao.insert(element).subscribeOn(Schedulers.io())...
    }
}

Then in

@Singleton
@Component(dependencies = {},modules = {AppModule.class, DatabaseModule.class})
public interface AppComponent {
    void inject(MainActivity mainActivity);
    void inject(ElementsActivity elementsActivity);
    void inject(ActivityElementsPresenter activityElementsPresenter);//will inject dependency to ActivityElementsPresenter.  
}
Related