java - 如何为 MortarActivityScope @Provide 一个 Activity,而不会在方向更改时泄漏 Activity?

标签 java android dagger mortar square-flow

我有一个 Mortar 应用程序,其中 MortarActivityScope 作为根范围下的第一个子级。 MortarActivityScope 有一个 ActivityScope,它 @Provides 一个注入(inject)类的 Activity :

@Module(addsTo = ApplicationModule.class, injects = {Foo.class, SomePresenter.class, AnotherPresenter.class})
public class ActivityModule {

    private final Activity activity;

    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    @Provides Activity provideActivity() {
        return activity;
    }
}

public class Foo {
    private final Activity activity;
    @Inject(Activity activity) {
        this.activity = activity;
    }
    public void doSomethingWithActivity() {
       // do stuff with activity: findViewById(), getWindow(), mess with action bar etc.
    }
}

这很好,直到方向发生变化。在 Mortar 示例项目中,Activity 范围不会因方向更改而被破坏。这大概是为了允许@Singleton 演示者、屏幕等在方向更改时保持不变。您可以在示例项目的主要 Activity 的 onDestroy() 方法中看到这一点:

@Override protected void onDestroy() {
    super.onDestroy();

    actionBarOwner.dropView(this);

    // activityScope may be null in case isWrongInstance() returned true in onCreate()
    if (isFinishing() && activityScope != null) {
      MortarScope parentScope = Mortar.getScope(getApplication());
      parentScope.destroyChild(activityScope);
      activityScope = null;
    }
  }
}

但是,这样做意味着旧的 ObjectGraph 在方向更改时仍然存在。我观察到 Mortar.requireActivityScope 不会用新蓝图提供的新模块替换旧 Activity 范围中的模块。相反,对象图保留对前一个模块的引用,包括已销毁的 Activity。

public class MyActivity extends Activity implements Blueprint {

    @Inject foo;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MortarScope parentScope = Mortar.getScope(getApplication());
        activityScope = Mortar.requireActivityScope(parentScope, this);
        Mortar.inject(this, this);

        foo.doSomethingWithActivity(); //fails, because activity injected by object graph is destroyed
    }

    @Override
    public String getMortarScopeName() {
        return getClass().getName();
    }

    @Override
    public Object getDaggerModule() {
        return new ActivityModule(this);
    }
}

Mortar 示例 Activity 似乎通过在主模块中不包含 @Provides Activity 方法来解决这个问题。但是 MortarActivityScope 不应该能够注入(inject) Activity 吗?在方向更改时不会丢失所有单例对象(Presenter 对象等)的首选方法是什么?

最佳答案

不允许任何人注入(inject)无法确保安全的 Activity 。而是注入(inject)一个绑定(bind)到 Activity 的演示者。

How to handle onActivityResult() with Mortar包括拥有演示者的 Activity 示例。然后,您应用的其他部分(包括其他演示者)可以注入(inject)该部分并要求它执行他们需要完成的任何需要处理 Activity 的事情。

并且没有必要将所有特定于 Activity 的工作绑定(bind)到一个 Activity 演示者中。我们的 Activity 有多个演示者将其服务代理给应用程序的其余部分。

关于java - 如何为 MortarActivityScope @Provide 一个 Activity,而不会在方向更改时泄漏 Activity?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26533621/

相关文章:

android - 如何为调试构建包含 Dagger Debug SubModule?

android - 如何使用 Dagger 2 在 Android 服务中注入(inject)单例

java - 我在 jdbc 中使用 localhost 时发现网络连接错误

java - AlertDialog 上的 android-setAdapter 不工作

java - Docker id 未选择文件

android - 使用 Espresso 运行 UI 测试,如何在 Material Design 芯片布局中引用关闭图标?

android - 我们可以通过 GOOGLE APIs 模拟器测试应用内购买 android 应用程序吗

android - 如果没有 @Inject 构造函数或 @Provides-annotated 方法,则无法提供 java.lang.String

java - 如何编写线程安全操作并使它们原子化?

java - 如何在ireport中创建动态列?