如何为MortarActivityScope提供一个活动,而不会在方向更改时泄露活动?

wee*_*ton 5 java android dagger mortar square-flow

我有一个Mortar应用程序,MortarActivityScope是根范围内的第一个孩子.MortarActivityScope有一个ActivityScope,@为注入类提供一个活动:

@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.
    }
}
Run Code Online (Sandbox Code Playgroud)

这种情况很好,直到方向发生变化.在Mortar示例项目中,不会在方向更改时销毁活动范围.这可能是为了让@Singleton演示者,屏幕等能够在方向变化中持续存在.您可以在示例项目的主要活动中的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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,这样做意味着旧的ObjectGraph会在方向更改中持续存在.我观察到,Mortar.requireActivityScope不会将旧活动范围中的模块替换为新蓝图提供的新模块.相反,对象图保留对前一个模块的引用,包括销毁的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mortar样本活动似乎通过不包括@Provides Activity主模块中的方法来解决这个问题.但是不MortarActivityScope应该能够注入活动吗?在不Presenter改变方向变化的所有单个对象(对象等)的情况下,首选方法是什么?

rjr*_*rjr 5

不要让任何人注入活动,这是不安全的.而是注入与Activity绑定的演示者.

如何使用Mortar处理onActivityResult()包含拥有演示者的Activity的示例.您的应用程序的其他部分(包括其他演示者)可以注入该应用程序,并要求它执行需要处理活动所需的任何操作.

并且不需要将所有特定于活动的工作绑定到单个活动演示者中.我们的活动有几位演示者将其服务代理到应用程序的其余部分.