Reputation: 714
I am following coding with mitch's dagger 2 course from youtube.I am confused about something.Here is my classes: AppComponent.class
@Singleton
@Component(
modules = {
AndroidSupportInjectionModule.class,
ActivityBuildersModule.class,
AppModule.class,
ViewModelFactoryModule.class,
}
)
public interface AppComponent extends AndroidInjector<BaseApplication> {
SessionManager sessionManager();
@Component.Builder
interface Builder{
@BindsInstance
Builder application(Application application);
AppComponent build();
}
}
ActivityBuildersModule
@Module
public abstract class ActivityBuildersModule {
@ContributesAndroidInjector(
modules = {AuthViewModelsModule.class,
AuthModule.class
}
)
abstract AuthActivity contributeAuthActivity();
@ContributesAndroidInjector
abstract MainActivity contributeMainActivity();
}
BaseActivity
public abstract class BaseActivity extends DaggerAppCompatActivity {
private static final String TAG = "BaseActivity";
@Inject
public SessionManager sessionManager;//confused here
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
subscribeObservers();
}
private void subscribeObservers() {
sessionManager.getAuthUser().observe(this, userAuthResource -> {
if (userAuthResource != null) {
switch (userAuthResource.status) {
case LOADING: {
break;
}
case AUTHENTICATED: {
Log.d(TAG, "subsrcibeObservers: LOGIN SUCCESS:" + userAuthResource.data.getEmail());
break;
}
case ERROR: {
Toast.makeText(this, userAuthResource.message, Toast.LENGTH_SHORT).show();
break;
}
case NOT_AUTHENTICATED: {
navLoginScreen();
break;
}
}
}
});
}
private void navLoginScreen(){
Intent intent = new Intent(this, AuthActivity.class);
startActivity(intent);
finish();
}
}
MainActivity
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
SessionManager
@Singleton
public class SessionManager {
private static final String TAG = "SessionManager";
private MediatorLiveData<AuthResource<User>> cachedUser = new MediatorLiveData<>();
@Inject
public SessionManager() {
}
public void authenticaWithId(final LiveData<AuthResource<User>> source) {
if (cachedUser != null) {
cachedUser.setValue(AuthResource.loading(null));
cachedUser.addSource(source, userAuthResource -> {
cachedUser.setValue(userAuthResource);
cachedUser.removeSource(source);
});
}
}
public void logOut(){
Log.d(TAG, "logOut: logging out...");
cachedUser.setValue(AuthResource.logout());
}
public LiveData<AuthResource<User>> getAuthUser(){
return cachedUser;
}
}
BaseApplication
public class BaseApplication extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().application(this).build();
}
}
My problem is @Inject SessionManager sessionManager
that statement in the BaseActivity.In the ActivityBuildersModule class, we only annotated MainActivity as a subcomponent, not the BaseActivity.Since the MainActivity is a subcomponent it can access dependencies of the AppComponent.So how we get accessed that SessionManager in the Base Activity or we get accessed that object because MainActivity is derived from BaseActivity?
Upvotes: 1
Views: 203
Reputation: 34522
Dagger will inject any annotated fields and methods of the declared parameter type and its supertypes. You can also read about it on the JavaDoc:
Members-injection methods
Members-injection methods have a single parameter and inject dependencies into each of the Inject-annotated fields and methods of the passed instance.
[...]
A note about covariance
While a members-injection method for a type will accept instances of its subtypes, only Inject-annotated members of the parameter type and its supertypes will be injected;
So if you have a SubActivity < BaseActivity < AppCompatActivity
then declaring the method as inject(activity: BaseActivity)
would only inject fields of BaseActivity
and any supertypes, wheras inject(activity: SubActivity)
will inject SubActivity
as well as any parent/supertypes (BaseActivity
in this example, your observed behavior).
Upvotes: 2