I'm following an MVC pattern for my Android application and have ran into this issue a few times and have had to work around it. When my application is able to create an injected object using the @Inject annotation on a field, that objects @Inject fields are null, usually causing a crash. For instance, I have controller classes that will handle logic and flow. Any Fragments/Activities will callback to their controller to notify of a user interaction / state change. However, the injected instance of Controller is usually null.
I'll give a simple example to illustrate. Below, the Controller is having an injected activity created, then using that to start flow by adding a Fragment. That dependency is handled but the Activities dependency on the controller is not (i.e. null).
Simple Controller class to handle business logic and flow:
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...
}
}
The simple activity that handles user interaction and calls back to the controller to perform some business logic:
public class SomeActivity extends Activity {
@Inject
SomeController controller;
private void controllerCallback() {
//notify controller of something here...
}
}
Simple Module class for injecting objects into graph:
@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();)
}
Simple Component class for providing methods to consume objects:
@Component
public interface SomeComponent {
void addController(SomeController controller);
SomeController controller();
SomeActivity activity();
}