使用Dagger注入模块中的字段

4
我正在尝试将我的Android上下文从一个模块注入到另一个模块。这是我目前的代码:
UserProfileModule.java
@Module(
        library = true
)
public class UserProfileModule {

    @Inject Context _context;

    @Provides
    public AccountUtils.UserProfile provideUserProfile() {
        return AccountUtils.getUserProfile(_context);
    }
}

RootModule.java

@Module(
        injects = {
                PizzaApplication.class,
                UserProfileModule.class,
                MainActivity.class
        },
        includes = {
                UserProfileModule.class
        },
        library = true
)

public class RootModule {
    private final Context _context;

    public RootModule(Context context) {
        _context = context;
    }

    @Provides
    @Singleton
    public Context provideApplicationContext() {
        return _context;
    }
}

每当它尝试获取用户配置文件时,都会失败并显示对象为空。
编辑:
PizzaApplication.java
public class PizzaApplication extends Application {
    private ObjectGraph objectGraph;

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

    private void injectDependencies() {
        objectGraph = ObjectGraph.create(new RootModule(this));
        objectGraph.inject(this);
    }

    public void inject(Object object) {
        objectGraph.inject(object);
    }
}

MainActivity.java

public class MainActivity extends BaseActivity {

    @InjectView(R.id.toolbar) public Toolbar _toolbar;
    @InjectView(R.id.drawer) public DrawerFrameLayout _drawer;
    @Inject public AccountUtils.UserProfile _profile;
    @Inject public Context _context;

    // private NavigationDrawerFragment navigationDrawerFragment;

    @Override
    protected void onCreate(Bundle saveInstanceState) {

啊,这就是问题所在。你应该自己注入实例。在你的Activity中,调用'objectGraph.inject(this)`。请参考Dagger文档中的示例。 - nhaarman
我在BaseActivity的onCreate方法中调用了那个方法。抱歉我没有包含那个。 - Coder2000
你能否也添加一下你是如何构建你的ObjectGraph的? - nhaarman
我目前很遗憾无法使用聊天功能。 - nhaarman
我已经创建了一个Gist,其中包含所有的代码,如果这样更容易阅读:https://gist.github.com/coder2000/38aafaaa2f5a2edcb6de - Coder2000
显示剩余6条评论
2个回答

6

简短版(tl;dr):

  1. 你可以在GitHub 上查看我的代码,它提供了一个最小化的工作示例。
  2. 你不需要/不应该将一个模块中的Context注入到另一个模块中。
  3. 你的模块includes的顺序/方向是相反的,UserProfileModule应该包括RootModule

更多关于你的代码的细节和评论:

  1. 你不需要将某个东西注入到模块中,模块只提供依赖项。在你的情况下,只需使用模块includes即可获得所需功能。
  2. UserProfileModule中删除library=true,因为只有当模块提供者没有直接被injects列表中指定的类使用时才需要这样做。
  3. 如Niek Haarman所说,你需要将RootModuleUserProfileModule实例都传递给PizzaApplication的onCreate方法中的ObjectGraph.create
  4. 你在PizzaApplication中执行inject(this),但它没有任何依赖项,所以注入是不必要的。基于你提供的示例代码,这使我认为你假定在应用程序级别上进行注入也会注入Activity依赖项...?你还需要在Activity中进行注入。
  5. 你没有展示在Activity的onCreate中是否执行了注入——这很可能是缺失的内容。
  6. 你将Context注入到Activity中,但这是不必要的,因为你可以在Activity中使用getApplicationContext()。

以下是可工作的代码:

RootModule:

@Module(
    injects = {MainActivity.class},
    library = true,
    complete = false
)
public class RootModule {
  private final Context _context;

  public RootModule(Context context) {
    _context = context;
  }

  @Provides
  @Singleton
  public Context provideApplicationContext() {
    return _context;
  }
}

UserProfileModule:

@Module(includes = {RootModule.class})
public class UserProfileModule {
  @Provides
  public AccountUtils.UserProfile provideUserProfile(Context context) {
    return AccountUtils.getUserProfile(context);
  }
}

MainActivity:

public class MainActivity extends BaseActivity {

  @Inject
  public AccountUtils.UserProfile _profile;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ((PizzaApplication) getApplication()).inject(this);
    _profile.message();
  }

PizzaApplication:

public class PizzaApplication extends Application {
  private ObjectGraph objectGraph;

  @Override
  public void onCreate() {
    super.onCreate();
    objectGraph = ObjectGraph.create(new RootModule(this), new UserProfileModule());
  }

  public void inject(Object object) {
    objectGraph.inject(object);
  }
}

0

你有

objectGraph = ObjectGraph.create(new RootModule(this));

但是,includes = { UserProfileModule.class } 并不是魔法。你必须自己创建它:

objectGraph = ObjectGraph.create(new RootModule(this), new UserProfileModule() );

此外,@Inject 注释在 Context 上不起作用。最好修改您的提供程序方法:
@Provides 
public AccountUtils.UserProfile provideUserProfile(Context context) { 
    return AccountUtils.getUserProfile(context);
}

我不能保证这会解决你所有的问题,但它会帮助你朝着正确的方向前进。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接