我有一个示例项目,其中使用dagger-android AndroidInjector注入依赖项。
在此示例应用程序中,我有一个Navigator
类,该类可以完成所有“从活动到活动”的导航,并且需要在构造函数中使用当前Activity
的实例。
我有一个AppModule
类,它向其他组件提供实例,该类也负责向我的演示者提供Navigator
的实例,但是Navigator
构造函数采用{{ 1}}作为Activity
中的参数。
如何将活动实例访问到AppModule
构造函数。
我尝试通过用Navigator
注解对Activity
成员变量进行注解来直接在Navigator
中注入Activity
的实例,但是在构建项目时会引发错误。
错误:[dagger.android.AndroidInjector.inject(T)]如果没有@Inject构造函数或@Provides注释的方法,则无法提供android.app.Activity。
注入了android.app.Activity我已经转介了其他SA帖子,但是这对我的查询没有帮助,或者可能是我无法理解那里给出的解决方案。 以下是我关注的帖子
How to inject current activity in a collaborator using Dagger 2.11 Android injector
How to get MainActivity inside a module using AndroidInjector
下面是我实现的代码:
Application.Java
@Inject
MainActivity.java
public class MyApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> androidInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return androidInjector;
}
}
MyPresenter.Java
public class MainActivity extends BaseActivity implements BaseView {
@Inject
Context application;
@Inject
MainPresenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
}
Navigator.Java
public class MyPresenter extends BasePresenter<IActivityView> {
private final NavigationRouter mNavigationRouter;
@Inject
public MyPresenter(Navigator navigatr) {
mNavigationRouter = navigationRouter;
}
}
ActivityBuilder.java
//This is how my Navigator is currently.
public class Navigator{
Activity mActivity;
@Inject
public Navigator(Activity activity){
mActivity = activity;
}
}
AppModule.Java
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector
abstract MainActivity bindMainActivity();
@ContributesAndroidInjector
abstract LoginActivity bindLoginActivity();
}
AppComponent.Java
@Module
public class AppModule {
//How can i have the instance of current activity in this module class.
@Provides
@Singleton
NavigationRouter providesNavigationRouter(Activity activity) {
//Here I want the instance of current activity
return new NavigationRouter(activity);
}
}
在此方面的任何帮助将不胜感激。
我已经更新了代码段,以使其更加清晰
答案 0 :(得分:1)
在此示例应用程序中,我有一个导航器类,它可以完成所有 从活动到活动导航,它需要以下实例 构造函数中的当前活动
我对预期的工作方式有些困惑。这是否意味着每个Activity
都会创建自己的Navigator
?如果Activity是通过构造函数提供的,那么我想不出其他任何可行的方法。
无论如何,假设您确实想为每个活动创建一个Navigator
,那么Dagger设置将如下所示:
MainActivityModule.java
@Module
public abstract class MainActivityModule {
@Binds @Named(MainActivity.class.getSimpleName()) abstract Navigator navigator(MainActivity ma);
}
ActivityBuilder.java
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity bindMainActivity();
}
MainActivity.java
public class MainActivity extends BaseActivity implements BaseView {
@Inject Navigator navigator; //This will hold a reference to MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this); //Or AndroidSupportInjection...
}
}
编辑: 我提出了几点意见,表明通过其构造函数使用单个Activity的“ Navigator”类是不可行的。您可以尝试以下方法:
@Singleton
public final class Navigator {
private WeakReference<BaseActivity> ref = null;
@Inject
Navigator(){}
void setForegroundActivity(BaseActivity base) {
this.ref = new WeakReference<>(base);
}
void transitionTo(Class<? extends BaseActivity> next) {
if(ref == null) return;
final BaseActivity current = ref.get();
if(current != null) {
current.transitionTo(next);
}
}
}
public class MyApp extends Application implements Application.ActivityLifecycleCallbacks {
@Inject Navigator navigate;
//...
void onActivityResumed(Activity activity) {
if(activity instanceof BaseActivity) {
navigate.setForegroundActivity((BaseActivity) activitiy);
}
}
}
public class AnExampleClass {
private final Navigator navigate;
@Inject
AnExampleClass(Navigator navigate) {
this.navigate = navigate;
}
//...
void someMethodRequiringATransition() {
navigator.transitionTo(AnotherActivity.class);
}
}
public class AnExampleActivity extends BaseActivity {
@Override
public void transitionTo(Class<? extends BaseActivity> next) {
if(AnotherExampleActivity.class.equals(next)) {
//Do stuff specific to transitioning to "Another Example Activity"
}
}
}
我之所以使用WeakReference
是因为将Activity单独存储是危险的,并且有效地避免了内存泄漏。但是,您也可以使用ActivityLifecycleCallbacks
删除“活动”,因为它们也会移入“ onPause”。