首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用AndroidInjector获取模块类中的活动实例?

如何使用AndroidInjector获取模块类中的活动实例?
EN

Stack Overflow用户
提问于 2019-07-01 06:38:45
回答 1查看 1.4K关注 0票数 1

我有一个示例项目,在其中我使用匕首-android AndroidInjector注入依赖项。在这个示例应用程序中,我有一个类Navigator,它执行活动导航的所有活动,并在它的构造函数中要求当前Activity的实例。

我有一个AppModule类,它将实例提供给另一个组件,它还负责将Navigator的实例提供给我的演示者,但是Navigator构造函数从AppModule中接受Activity作为参数。如何将活动实例访问到Navigator构造函数。我尝试将Activity实例直接注入到Navigator中,方法是用@Inject注释注释Activity成员变量,但这会在构建项目时引发错误。

错误: dagger.android.AndroidInjector.inject(T) android.app.Activity不能在没有@Inject构造函数的情况下提供,也不能从@Provi富于注释的方法中提供。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

代码语言:javascript
复制
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;
    }
}

MainActivity.java

代码语言:javascript
复制
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);
    }
}

MyPresenter.Java

代码语言:javascript
复制
public class MyPresenter extends BasePresenter<IActivityView> {

    private final NavigationRouter mNavigationRouter;

    @Inject
    public MyPresenter(Navigator navigatr) {
        mNavigationRouter = navigationRouter;
    }

}

Navigator.Java

代码语言:javascript
复制
//This is how my Navigator is currently.
public class Navigator{

    Activity mActivity;

    @Inject
    public Navigator(Activity activity){
    mActivity = activity;
    }

}

ActivityBuilder.java

代码语言:javascript
复制
@Module
public abstract class ActivityBuilder {

    @ContributesAndroidInjector
    abstract MainActivity bindMainActivity();

    @ContributesAndroidInjector
    abstract LoginActivity bindLoginActivity();
}

AppModule.Java

代码语言:javascript
复制
@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);
    }
}

AppComponent.Java

代码语言:javascript
复制
@Component(modules = {
        AndroidInjectionModule.class,
        AppModule.class,
        ActivityBuilder.class})
@Singleton
public interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(MyApplication application);
}

在这方面的任何帮助将是非常感谢的。

我已经更新了代码片段以获得更清晰的

EN

回答 1

Stack Overflow用户

发布于 2019-07-01 06:59:10

在这个示例应用程序中,我有一个类Navigator,它执行所有的活动到活动导航,它需要当前活动的实例在它的构造函数中

我有点搞不懂这是怎么回事。这是否意味着每个Activity都会创建自己的Navigator?如果活动是通过构造函数提供的,那么我想不出任何其他可行的方法。

无论如何,假设您确实希望为您的每个活动创建一个Navigator,那么Dagger设置将如下所示:

MainActivityModule.java

代码语言:javascript
复制
@Module
public abstract class MainActivityModule {
    @Binds @Named(MainActivity.class.getSimpleName()) abstract Navigator navigator(MainActivity ma);
}

ActivityBuilder.java

代码语言:javascript
复制
@Module
public abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = MainActivityModule.class) 
    abstract MainActivity bindMainActivity();
}

MainActivity.java

代码语言:javascript
复制
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...
    }
}

编辑:--我提出了几点意见--显示"Navigator“类通过构造函数接受单个活动的注释是不可行的。您可以尝试这样做:

代码语言:javascript
复制
@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);
        }
    }
}
代码语言:javascript
复制
public class MyApp extends Application implements Application.ActivityLifecycleCallbacks {

    @Inject Navigator navigate;

//...
   void onActivityResumed(Activity activity) {
        if(activity instanceof BaseActivity) {
            navigate.setForegroundActivity((BaseActivity) activitiy);
        }
    }

}
代码语言:javascript
复制
public class AnExampleClass {

    private final Navigator navigate;

    @Inject
    AnExampleClass(Navigator navigate) {
        this.navigate = navigate;
    }

    //...
    void someMethodRequiringATransition() {
        navigator.transitionTo(AnotherActivity.class);
    }

}
代码语言:javascript
复制
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,是因为将一个活动存储在单例中是危险的,并且有效地避免了内存泄漏。但是,您可以使用ActivityLifecycleCallbacks来删除活动,因为它们也会移动到"onPause“中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56830990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档