Use Dagger to inject the field… here is a solution to the problem.
Use Dagger to inject the field
I’m trying to inject my android context from one module to another. So far, here’s my code:
UserProfileModule.java
@Module(
library = true
)
public class UserProfileModule {
@Inject Context _context;
@Provides
public AccountUtils.UserProfile provideUserProfile() {
return AccountUtils.getUserProfile(_context);
}
}
The root module .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;
}
}
Whenever it tries to get the user profile, it fails and prompts that the object is empty. ]
Edit:
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);
}
}
The main activity .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) {
Solution
tl; dr (short version):
- For a minimal working example of code, see my code on GitHub
- You don’t/shouldn’t inject
Context
from one module to another. - order/direction of module
inclusions
is reversed, and UserProfileModule should contain RootModule.
The
More details and comments about your code:
- You don’t need to inject anything into the module, the module only provides dependencies. In your case, simply use the module
includes
to provide the functionality you want. - Remove
library = true
from theUserProfileModule
because youonly need it if the class specified in the inject list does not use the module's provider directly
. - As Niek Haarman says, you need to pass
the RootModule
andUserProfileModule
instances toObjectGraph.create
in PizzaApplication’s onCreate. - You are executing inject
(this) in PizzaApplication
, but it has no dependencies, so inject is not needed. Based on the sample code you provided, this makes me feel like you’re assuming that injecting at the application level will also inject activity dependencies…? You also need to inject your activity. - If you inject in the onCreate of the activity, it will not be displayed – this is most likely missing.
- You are injecting a Context into an activity, but this is not required because you can use getApplicationContext() in an activity.
Here is the working code:
Root module:
@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;
}
}
User Profile Module:
@Module(includes = {RootModule.class})
public class UserProfileModule {
@Provides
public AccountUtils.UserProfile provideUserProfile(Context context) {
return AccountUtils.getUserProfile(context);
}
}
Main Activity:
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();
}
Pizza app:
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);
}
}