如何使用AndroidInjector在Module类中获取活动实例?

时间:2019-07-01 06:38:45

标签: java android dagger-2 dagger androidinjector

我有一个示例项目,其中使用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);
    }
}

在此方面的任何帮助将不胜感激。

我已经更新了代码段,以使其更加清晰

1 个答案:

答案 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”。