使用匕首将字段注入模块

Cod*_*000 4 java android dagger

我正在尝试将我的 android 上下文从一个模块注入另一个模块。到目前为止,这是我的代码:

用户配置文件模块.java

@Module(
        library = true
)
public class UserProfileModule {

    @Inject Context _context;

    @Provides
    public AccountUtils.UserProfile provideUserProfile() {
        return AccountUtils.getUserProfile(_context);
    }
}
Run Code Online (Sandbox Code Playgroud)

根模块.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

每当它尝试获取用户配置文件时,它都会失败,说该对象为空。]

编辑:

比萨应用程序

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

主活动.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) {
Run Code Online (Sandbox Code Playgroud)

G. *_*ard 5

tl;博士(简短版本):

  1. 有关代码的最小工作示例,请参阅我在 GitHub 上的代码
  2. 您不需要/不应该将Context来自一个模块的注入到另一个模块中。
  3. 模块的顺序/方向includes相反,UserProfileModule 应包含 RootModule。

有关您的代码的更多详细信息和评论:

  1. 您不需要向模块中注入一些东西,模块只提供依赖项。在您的情况下,只需使用该模块即可includes提供您想要的功能。
  2. 删除library = truefrom UserProfileModule,因为只有在injects列表中指定的类没有直接使用模块的提供程序时才需要它。
  3. 正如 Niek Haarman 所说,您需要在 PizzaApplication 的 onCreate 中同时传递RootModuleUserProfileModule实例ObjectGraph.create
  4. 您正在inject(this)PizzaApplication 中进行操作,但它没有依赖项,因此不需要注入。根据您提供的示例代码,这让我认为您假设在应用程序级别注入也会注入 Activity 依赖项......?您也需要对您的 Activity 进行注入。
  5. 您不会显示您是否正在 Activity 的 onCreate 中进行注入 - 这很可能是缺少的内容。
  6. 您将 Context 注入到 Activity 中,但这不是必需的,因为您可以在 Activity 中使用 getApplicationContext()。

这是工作代码:

根模块:

@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;
  }
}
Run Code Online (Sandbox Code Playgroud)

用户配置文件模块:

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

主要活动:

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();
  }
Run Code Online (Sandbox Code Playgroud)

比萨应用:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)