@Inject字段的空对象



我的Android应用程序遵循MVC模式,已经遇到过几次这个问题,不得不解决它。当我的应用程序能够在字段上使用@Inject注释创建注入的对象时,对象@Inject字段为空,通常会导致崩溃例如,我有处理逻辑和流的控制器类。任何片段/活动都将回调到其控制器,以通知用户交互/状态更改。但是,注入的Controller实例通常为null。

我将举一个简单的例子来说明。下面,控制器创建了一个注入的活动,然后使用它通过添加一个片段来启动流。该依赖关系已处理,但控制器上的Activities依赖关系未处理(即为null)。

处理业务逻辑和流程的简单控制器类:

public class SomeController {
    @Inject
    SomeActivity someActivity;
    private SomeComponent component;
    private final Application app;
    @Inject
    public SomeController(Application app) {
        this.app = app;
    }
    private void startActivity() {
        component = Dagger_SomeComponent().builder()
             .someModule(app)
             .build();
        someActivity.getFragmentManager().beginTransaction().
            .add(R.id.content, SomeFragment.class, null)
            .commit();
    }
    public void activityStarted() {
        //callback when Activity is ready...
    }
}

处理用户交互并回调控制器以执行一些业务逻辑的简单活动:

public class SomeActivity extends Activity {
    @Inject
    SomeController controller;
    private void controllerCallback() {
          //notify controller of something here...
    }
}

用于将对象注入图中的简单模块类:

@Module
public class SomeModule {
    private Application app;
    public SomeModule(Application app) {
         this.app = app;
    }
    @Provides
    @Singleton
    SomeController provideSomeController( return new SomeController(app); )
    @Provides
    SomeActivity provideSomeActivity( return new SomeActivity();)
}

用于提供使用对象的方法的简单组件类:

@Component
public interface SomeComponent {
    void addController(SomeController controller);
    SomeController controller();
    SomeActivity activity();
}

我认为您的示例中遗漏了一些内容:

1) Dagger2组件是一些提供依赖关系的模块和一些"消耗"依赖关系的注入点之间的桥梁。您的组件应该至少有一个链接模块,注释应该如下所示:

@Component(modules = SomeModule.class)

2) 模块中带有"new"运算符的SomeActivity实例化没有意义。好吧,你可以创建活动对象,但谁来管理它的状态,调用它的生命周期方法等等?如果您真的想将现有"活动"的引用作为依赖项传递,这是可能的,但方式不同。例如,创建应用程序级模块&组件和单独的活动级别模块&组件,将现有的"活动"引用作为模块构造函数参数传递。

3) 活动是由Android框架创建的,因此您应该在活动中使用字段注入。在组件中添加一行,如:

void inject(SomeActivity activity);

并将创建组件的代码放入"活动"中。例如onCreate():

SomeComponent component = Dagger_SomeComponent().builder()
         .someModule(getApplication())
         .build()
         .inject(this);

4) 请尽量避免在开始时使用@Singleton注释。首先确保声明的所有依赖项都得到满足,并且不再为null。接下来,您可以检查一些现有的Dagger2开源项目,以进行正确的范围注释。

我遇到了这个问题,并使用这个公认的答案解决了它。

TLDR:我不得不在组件中添加inject()方法类型,而不仅仅是inject(SomeSuperclass foo)

基本上,我有一个需要注射的活动:

class SubActivity extends BaseActivity {
    @Inject Type someVar;
    @Override
    protected void onCreate(Bundle bundle) {
       getComponent().inject(this);
    }
}

但我的组件看起来像:

@Component
public interface MyComponent {
    void inject(BaseActivity activity); // This allows SubActivity to compile but messes up injection
}

解决方案:为确切的子类型添加注入方法:

@Component
public interface MyComponent {
    void inject(BaseActivity activity);
    void inject(SubActivity activity); //<-- This solved it
}

在我的案例中,dependents="bean1"在应用程序上下文中的属性占位符中导致了问题。我使用@PostConstruct使注入工作。

最新更新