gpt4 book ai didi

android - 在 Dagger 中,子图内的单例是缓存的还是在构造新的 Activity 子图时总是重新创建它们?

转载 作者:行者123 更新时间:2023-11-29 21:01:32 26 4
gpt4 key购买 nike

我正在使用 Dagger 创建特定于 Activity 的对象图。在此子图中,我使用了单例 MyPresentationModel

当我退出 Activity 并再次进入 Activity 时,我的期望是创建 Activity 特定对象图的新实例,这又会创建单例 MyPresentationModel 的新实例( by virtue of the @Singleton semantic per Dagger. See this So answer for specifics ) 然后将持续到 Activity 特定对象图的生命周期。

但是,这不是我所观察到的,每次创建特定于 Activity 的对象图时,都会使用相同的 MyPresentationModel 实例。我在 MyPresentationModel 的构造函数中添加了一个调试点。我们第一次进入构造函数。随后,即使在 Activity 退出和重新进入时,我们也不会进入构造函数(因此,在我的 Presentation 模型中使用的 UserSession 使用了第一个构造函数注入(inject)中的旧值)。

虽然我可以通过使用外部公共(public) setter 在 MyPresentaitonModel 中重新设置 UserSession 来从技术上解决问题,但我想更好地理解 Activity 特定对象图创建/销毁的机制。

通过在我的 onDestroy 中取消图,这是否仍然意味着我的子图中的单例有可能在以后被重用? (可能直到它们真正被 GC 处理为止?)

这是一些代码:

 // MyAppModule
@Module(
includes = { UserSession.class},
injects = { MyApplication.class })
public class MyAppModule {

private final MyApplication _app;

MyAppModule(MyApplication app) {
_app = app;
}
// ...
}


// Main Activity

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

_activityObjectGraph = MyApplication.get()
.getObjectGraph()
.plus(Arrays.<Object>asList(new SubModule()).toArray());

// Inject ourselves so subclasses will have dependencies fulfilled when this method returns.
_activityObjectGraph.inject(this);
}

@Override
protected void onDestroy() {
_activityObjectGraph = null;
// this eagerly allows GC, but doesn't necessarily destroy the subgraph ?
super.onDestroy();
}

// SubModule
@Module(injects = { MyPresentationModel.class, MainActivity.class },
addsTo = MyAppModule.class,
library = true)
public class SubModule {}

}

// MyPresentationModel
@Singleton
public class MyPresentationModel {

private UserSession _session;

@Inject
public MyPresentationModel(UserSession session) {
_session = session;
}

public void someMethodThatUsesSessionInfo() {
// _session.getUser() ...
}
}

@weefbellington 发布了一个非常有用的答案,但阅读它让我意识到我的问题不够具体和清楚。这是尝试 2:

MyAppModule(主图)-> 提供一个 Singleton UserSession

MySubModule(子图加到 MyAppModule 上)-> 提供“特定于 Activity 的”单例 MyPresentationModel,它需要一个 UserSession(提供我的 MyAppModule)关于 build 。

我现在关闭 Activity,销毁 MySubModule(也希望 MyPresentationModel 是一个 Singleton),我用一些新信息更新 UserSession。

我再次打开 MainActivity,从而从 MySubModule 重新创建子图,它又提供了一个 MyPresentationModel

我注意到的问题是作为本地 Singleton 的 MyPresentationModel 没有被再次重建,即这部分代码:

  @Inject
public MyPresentationModel(UserSession session) {
_session = session;
}

只会被调用一次。我的期望是这部分代码会再次运行,并且 UserSession 会再次从 Main 图中拉出,因为它已更新,所以它会保存更新后的值。我的问题是:子图中的单例是否以任何方式缓存,或者在生成新的 Activity 子图时是否总是会重新创建它们?

最佳答案

MyPresentationModule 的注入(inject)方式取决于您的模块是如何指定的。例如,假设您正在注入(inject)类 Foo:

public class Foo {
private final MyPresentationModel model;
@Inject
public Foo(MyPresentationModel model) {
this.model = model;
}
}

如果您的模块结构类似于 (A),则 MyPresentationModel 单例将被主对象图注入(inject)到 Foo 中:

示例 A

@Module(injects = { Foo.class })
public class MainModule { ... }

@Module(addsTo = MainModule.class, injects = { MyPresentationModel.class })
public class SubModule { ...}

或者,如果您的模块结构类似于 (B),则 MyPresentationModel 单例将通过子图注入(inject) Foo:

示例 B

@Module
public class MainModule { ... }

@Module(addsTo = MainModule.class, injects = { Foo.class, MyPresentationModel.class })
public class SubModule { ... }

在您的特定情况下,由于您已指定 MyAppModule 注入(inject) MyApplication,我猜您正试图将 MyPresentationModel 注入(inject)您的应用类。这可能不是您想要做的。您可能希望使用子模块将其注入(inject)到 Activity 类中,如 (C) 中所示。

示例 C

@Module(injects = { MainActivity.class, MyPresentationModel.class },
addsTo = MyAppModule.class,
library = true)
public class SubModule { ... }

public class MainActivity {
@Inject MyPresentationModel presentationModel;
...
}

如果您这样做,MyPresentationModel 单例将绑定(bind)到 Activity 子图而不是主图,并且应该在 Activity 被销毁时被释放。

掌握了 Dagger 后,您可能想查看 Mortar ,这使您可以更精细地控制 ObjectGraph 子范围的创建和销毁。

关于android - 在 Dagger 中,子图内的单例是缓存的还是在构造新的 Activity 子图时总是重新创建它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25953525/

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