gpt4 book ai didi

android - Dagger 不断拒绝注入(inject)依赖

转载 作者:行者123 更新时间:2023-11-30 02:31:59 26 4
gpt4 key购买 nike

不幸的是,我什至没有使用最简单的 Dagger 示例。让我们看看我的代码(我去掉了大部分 UI 和自动生成的代码,因为它们不相关):

  • 我的 Activity

    public class MainActivity extends ActionBarActivity {
    @Inject
    RoomDAO roomDAO;
    private ObjectGraph objectGraph;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    objectGraph = ObjectGraph.create(RoomModule.class);
    roomDAO = objectGraph.get(RoomDAO.class);
    roomDAO.hai();
    }

    }
  • RoomDAO 和 RoomDAOImpl

    public interface RoomDAO {
    String hai();
    }

    public class RoomDAOImpl implements RoomDAO {
    private DBHelper dbHelper;

    @Inject
    public RoomDAOImpl(){
    //I tried even this constructor in case dbHelper was the guy causing problems,
    //but it wasn't!
    }


    public RoomDAOImpl(DBHelper dbHelper){
    this.dbHelper = dbHelper;
    }
    @Override
    public String hai() {
    return "oh hai";
    }
    }
  • 房间模块

    @Module(
    injects = {MainActivity.class},
    library = true
    )
    public class RoomModule {
    @Provides @Singleton
    public RoomDAO provideRoomDao(){
    return new RoomDAOImpl();
    }
    }

DBHelper 没有任何有趣的东西(只是一些小的数据库东西,onCreate,onUpdate,没有更多)。

我认为那行 roomDAO = objectGraph.get(RoomDAO.class); 会让 Dagger(或多或少)调用 RoomModule#provideRoomDao() 并让我成为一个好人,全新的 RoomDAOImpl 对象(如果已经创建,则从天而降)。但是,我的图表在 injectableTypes 中没有 RoomDAO,因此我的应用程序在 roomDAO = objectGraph.get(RoomDAO.class); 行失败在调用 ObjectGraph#getInjectableTypeBinding 时(因为 moduleClass == null)。我错过了什么?

编辑。
好的,可能是时候展示 DBHelper 的样子了。

public class DBHelper extends SQLiteOpenHelper {
// (...) not relevant config stuff i.e. DATABASE_NAME, DATABASE_VERSION

@Inject
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
//(...) creating tables
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//(...) updating tables
}
}


@Module(
injects = {MainActivity.class}
)
public class RoomModule {
@Provides @Singleton
public RoomDAO provideRoomDao(DBHelper dbHelper){
return new RoomDAOImpl(dbHelper);
}

@Provides
public Context getAppContext(){
return MainActivity.getAppContext();
}
}


我决定使用您建议的第二种方法,因为它似乎更像 Spring,而且我对此更熟悉。
MainActivity.getAppContext();是一个静态方法,返回静态字段Context的值。这有点尴尬,但如果涉及到 Context,我是非常无知的,因为我从未见过它的真正用法(我总是把 this 放在我需要 Context 的地方)。
这就是问题所在 - RoomModule#getAppContext() 似乎是错误的可能来源吗? DBHelper 可能没问题,因为它是一个单例,一旦创建,理论上应该随处可用。向这个人添加一些限定符 @Provides public Context getAppContext() 会让这个解决方案或多或少没有错误吗?或者也许有更好的方法为 DBHelper 构造函数提供上下文?

最佳答案

首先,删除 library = true 行。不要只添加 library = truecomplete = false,尤其是在基本示例中。这些行隐藏了有用的警告。

运行应用程序时,您将得到一个IllegalArgumentException:

Caused by: java.lang.IllegalArgumentException: No inject registered for tmp.RoomDAO. You must explicitly add it to the 'injects' option in one of your modules.

有两种方法可以从 ObjectGraph 中检索实例,使用 get(...) 或使用 inject(...).

  • 当使用 get(...) 时,您需要将您尝试获取的类添加到模块中的 injects 选项(例如异常告诉你):

    @Module(injects = {MainActivity.class, RoomDAO.class})

    这将使您的应用程序正常工作。实际上,您的 RoomDAO 字段上不需要 @Inject 注释。

  • 另一种方法是使用inject,您确实需要@Inject 注释。 inject 查看类的注释字段,并使用 ObjectGraph 为它们赋值。使用此方法,您无需将 RoomDAO 添加到模块的 injects 选项中:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    objectGraph = ObjectGraph.create(RoomModule.class);
    objectGraph.inject(this);
    roomDAO.hai();
    }

最后,您的 RoomDAOImpl 依赖于 DBHelper。为了完整起见,您可以这样做:

数据库助手:

public class DBHelper {
@Inject
public DBHelper() {
}
}

房间模块:

@Module(
injects = {MainActivity.class}
)
public class RoomModule {

@Provides
@Singleton
public RoomDAO provideRoomDao(DBHelper dbHelper) {
return new RoomDAOImpl(dbHelper);
}
}

RoomDAOImpl:

public class RoomDAOImpl implements RoomDAO {

private final DBHelper mDBHelper;

public RoomDAOImpl(final DBHelper dbHelper) {
mDBHelper = dbHelper;
}

@Override
public String hai() {
return "oh hai";
}
}

provideRoomDao 中的 DBHelper 实例是由 Dagger 为您创建的。为此,Dagger 需要在 DBHelper 的构造函数上添加一个 @Inject 注释。由于您自己实例化了 RoomDAOImpl,因此您不需要将 @Inject 注解添加到 RoomDAOImpl 的构造函数中。

关于android - Dagger 不断拒绝注入(inject)依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27218620/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com