gpt4 book ai didi

java - 如何使用 AndroidInjector 获取模块类中的 Activity 实例?

转载 作者:行者123 更新时间:2023-11-29 23:02:31 26 4
gpt4 key购买 nike

我有一个示例项目,我在其中使用 dagger-android AndroidInjector 来注入(inject)依赖项。在此示例应用程序中,我有一个 Navigator 类,它执行所有 Activity 到 Activity 的导航,它需要在其构造函数中包含当前 Activity 的实例。

我有一个 AppModule 类,它向其他组件提供实例,该组件还负责向我的演示者提供 Navigator 的实例,但是 Navigator 构造函数将 Activity 作为 AppModule 的参数。我怎样才能将 Activity 实例访问到 Navigator 构造函数。我已经尝试通过使用 @Inject 注释注释 Activity 成员变量来直接在 Navigator 中注入(inject) Activity 的实例,但是在构建项目时抛出错误。

错误:[dagger.android.AndroidInjector.inject(T)] android.app.Activity 无法在没有@Inject 构造函数或@Provides 注释方法的情况下提供。 android.app.Activity 被注入(inject)

我已经引用了其他 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

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

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

public class MyPresenter extends BasePresenter<IActivityView> {

private final NavigationRouter mNavigationRouter;

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

}

Navigator.Java

//This is how my Navigator is currently.
public class Navigator{

Activity mActivity;

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

}

ActivityBuilder.java

@Module
public abstract class ActivityBuilder {

@ContributesAndroidInjector
abstract MainActivity bindMainActivity();

@ContributesAndroidInjector
abstract LoginActivity bindLoginActivity();
}

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

AppComponent.Java

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

如有任何帮助,我们将不胜感激。

为了更清晰,我更新了代码 fragment

最佳答案

In this sample app I have a class Navigator which does all the Activity to Activity navigation and it requires the instance of current Activity in it's Constructor

我对它的预期工作方式有点困惑。这是否意味着每个 Activity 都会创建自己的 Navigator?如果 Activity 是通过构造函数提供的,那么我想不出任何其他可行的方法。

无论如何,假设您确实想为每个 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 在 Activity 进入“onPause”时删除它们。

关于java - 如何使用 AndroidInjector 获取模块类中的 Activity 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56830990/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com