Dagger 2 - 使用自定义范围时,依赖关系不是单例

时间:2018-06-17 09:14:05

标签: android dagger-2 dagger

我有自定义范围:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity { }

和使用此注释的组件:

@PerActivity
@Component(modules = {ActivityModule.class}, dependencies = AppComponent.class)
public interface ActivityComponent {

    void inject(MainActivity mainActivity);

}

和提供MainPresenter依赖关系的模块:

@Module
public class ActivityModule {

    @PerActivity
    @Provides
    public MainPresenter provideMainPresenter(){
        return new MainPresenter();
    }

}

这是MainPresenter注入的MainActivity:

public class MainActivity extends AppCompatActivity implements MainView {

    @PerActivity
    @Inject
    MainPresenter mainPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerActivityComponent.builder()
                .appComponent(DaggerAppComponent.builder().build())
                .build()
                .inject(this);

    }

}

我的问题:在配置更改(方向更改)后重新创建演示者。

我的问题:如何让它只为一项活动创建一次?

1 个答案:

答案 0 :(得分:5)

Dagger创建的Java代码没有任何魔力。这是一些可以做一些事情的类,但它们不会读/写全局状态或有其他副作用。如果创建组件,则创建它包含的所有对象。由一个组件提供的@PerActivity范围对象永远不会与从同一范围的另一个组件提供的对象相同。

MyComponent.create().getPresenter() == MyComponent.create().getPresenter() // always false (with same scope)

这就是说,你的代码示例中有一个主要问题,即你有一个AppComponent,但你不断重新创建它,很可能而不是你想要的或者应该这样做。这将为每个活动重新创建@Singleton

DaggerActivityComponent.builder()
    .appComponent(DaggerAppComponent.builder().build()) // DON'T !!
    .build()
    .inject(this);

您需要在Application类中缓存此组件并检索它,例如像((MyApp) getApplication).getComponent()这样的东西。否则,您的@Singleton类都不会被重用。

所有这些说明,当您在@PerActivity方法中创建新的ActivityComponent(DaggerActivityComponent.build())时,作用域onCreate的演示者将始终是新对象。您重新创建组件,该新组件将创建新对象。这是预期的行为,因为否则会出现内存泄漏和其他意外的副作用。 (想象一下,演示者保留了对活动的引用!内存将泄漏,UI更新将崩溃或被忽略。)

要重复使用同一个演示者,您必须将演示者移动到范围内。您可以将演示者设为@Singleton并将其保存在AppComponent中,也可以尝试在中间添加另一层组件(AppComponent -> ActivityCacheComponent -> ActivityComponent),但大多数我见过的项目不会添加这个中间层,因为它增加了很多复杂性。你要么拥有保存数据的单身,而且应该是长寿的,或者你有便宜的创作者,可以与活动一起轻松地重新创建。