@Inject 在 BaseActivity 中

@Inject in BaseActivity

我正在学习 youtube.I 的 mitch's dagger 2 课程编码,我对 something.Here 是我的 class 感到困惑: 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();

}

基地Activity

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

}

主要Activity

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

会话管理器

@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;
    }
}

基础应用程序

public class BaseApplication extends DaggerApplication {
    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerAppComponent.builder().application(this).build();
    }
}

我的问题是@Inject SessionManager sessionManager BaseActivity.In ActivityBuildersModule class 中的那个语句,我们只将 MainActivity 注释为子组件,而不是BaseActivity.Since MainActivity 是一个子组件,它可以访问 AppComponent.So 我们如何访问 Base Activity 中的 SessionManager 的依赖项,或者我们访问该对象是因为 MainActivity 派生自 BaseActivity?

Dagger 将注入声明的参数类型及其超类型的任何带注释的字段和方法。您还可以在 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;

因此,如果您有一个 SubActivity < BaseActivity < AppCompatActivity,那么将方法声明为 inject(activity: BaseActivity) 只会注入 BaseActivity 和任何超类型的字段,而 inject(activity: SubActivity) 将注入 SubActivity 以及任何 parent/supertypes(本例中的 BaseActivity 您观察到的行为 )。