简体   繁体   English

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

[英]How to @Provide an Activity for the MortarActivityScope, without leaking the Activity on orientation changes?

I have a Mortar application, with a MortarActivityScope as the first child under the root scope. 我有一个Mortar应用程序,其中MortarActivityScope作为根作用域下的第一个孩子。 The MortarActivityScope has an ActivityScope which @Provides an activity for injected classes: MortarActivityScope有一个ActivityScope,它@Provided为注入的类提供一个活动:

@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.
    }
}

This is fine until an orientation change happens. 直到发生方向改变,这都很好。 In the Mortar sample project, the Activity scope is not destroyed on orientation changes. 在Mortar示例项目中,“方向”更改时不会破坏“活动”范围。 This is presumably to allow @Singleton presenters, screens etc. to persist across orientation changes. 大概是为了允许@Singleton演示者,屏幕等在方向更改时保持不变。 You can see this in the onDestroy() method in the sample project's main 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;
    }
  }
}

However, doing it this way means that the old ObjectGraph persists across orientation changes. 但是,以这种方式进行操作意味着旧的ObjectGraph会在方向变化时保持不变。 I have observed that Mortar.requireActivityScope does not replace the module from the old activity scope with the new module provided by the new Blueprint. 我观察到Mortar.requireActivityScope不会将旧活动范围中的模块替换为新蓝图提供的新模块。 Instead, the object graph retains a reference to the previous module, including the destroyed 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);
    }
}

The Mortar sample activity seems to get around this by not including a @Provides Activity method in the main module. Mortar示例活动似乎通过在主模块中不包括@Provides Activity方法来解决此问题。 But shouldn't the MortarActivityScope be able to inject an Activity? 但是MortarActivityScope不能注入一个Activity吗? What's the preferred way to do this, without losing all of your singleton objects ( Presenter objects, etc.) on orientation change? 在不改变方向而丢失所有单例对象( Presenter对象等)的情况下,执行此操作的首选方法是什么?

Don't allow anyone to inject the Activity, that can't be made safe. 禁止任何人注入活动,这是不安全的。 Instead inject a presenter that is tied to the Activity. 而是注入与该活动相关的演示者。

How to handle onActivityResult() with Mortar includes an example of an Activity owning a presenter. 如何使用Mortar处理onActivityResult()包括一个拥有演示者的Activity的示例。 Other parts of your app, including other presenters, can then inject that one and ask it to do whatever it is they need done that requires dealing with the activity. 然后,您的应用程序的其他部分(包括其他演示者)可以注入该请求,并要求它执行需要处理的活动。

And there is no need to tie all activity-specific work into a single activity presenter. 而且,无需将所有特定于活动的工作捆绑到一个活动演示者中。 Our activity has several presenters that broker its services to the rest of the app. 我们的活动有几个演示者,他们将其服务代理到该应用程序的其余部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM