@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
, 您观察到的行为 )。
我正在学习 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
, 您观察到的行为 )。