【问题标题】:Dao is null while using Dagger2使用 Dagger2 时 Dao 为空
【发布时间】:2021-02-01 19:04:22
【问题描述】:

当我在 Presenter 中调用 DAO 时,它返回 null 并导致 NPE。 这里有一些代码: DAO 类

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

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

模块类:

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

组件类

@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 类(在清单中声明)

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

还有主持人

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

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

更新 AppDatabase 类

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

在调试时,我在 Presenter 中设置了一个点,发现 dao 没有初始化 elementsDao 尝试使用 App.getAppComponent().elementsDao(); 之类的东西,但它也可以使用。

【问题讨论】:

  • 可以添加AppDatabase类的代码
  • 不在此处,添加到您的问题中,此处不可读。
  • @rahat 抱歉,问题已更新
  • 您如何获得ActivityElementsPresenter 的实例?
  • 可以添加MvpPresenter的代码吗,MvpPresenter是所有presenter的基类吗?

标签: java android android-room dagger-2


【解决方案1】:

你需要这样做,

@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())...
    }
}

然后在

@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.  
}

【讨论】:

  • 现在对于每个presenter,你必须在AppComponent中添加一个抽象方法,并在构造函数中调用inject方法。
  • 如果你使用 BasePresenter 模式,那么注入对你来说会更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
相关资源
最近更新 更多