使用匕首将字段注入模块

时间:2015-02-21 21:20:19

标签: java android dagger

我正在尝试将我的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) {

2 个答案:

答案 0 :(得分:4)

tl; dr(短版):

  1. 有关代码的最小工作示例,请参阅my code on GitHub
  2. 您不需要/不应该将Context从一个模块注入另一个模块。
  3. 模块includes的顺序/方向相反,UserProfileModule应包含RootModule。
  4. 有关您的代码的更多详情和评论:

    1. 您不需要在模块中注入内容,模块只提供依赖项。在您的情况下,只需使用模块includes即可获得所需的功能。
    2. library = true移除UserProfileModule,因为只有在injects列表中指定的类不直接使用模块的提供者时才需要这样做
    3. 正如Niek Haarman所说,您需要将RootModuleUserProfileModule个实例传递到您的PizzaApplication onCreate中的ObjectGraph.create
    4. 你在PizzaApplication中做inject(this)但它没有依赖关系,所以注入是不必要的。根据您提供的示例代码,这让我觉得您认为在应用程序级别注入也会注入Activity依赖项......?你也需要对你的活动进行注入。
    5. 如果您在“活动创建”活动中注册,那么您很可能无法展示 - 这很可能是您所缺失的内容。
    6. 您已将Context注入活动,但这不是必需的,因为您可以在活动中使用getApplicationContext()。
    7. 这是工作代码:

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

答案 1 :(得分: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);
}

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