Ho un'applicazione Mortar, con un MortarActivityScope come primo figlio nell'ambito della radice. Il MortarActivityScope ha un ActivityScope che @Provides un'attività per classi iniettati:Come @Provide un'attività per MortarActivityScope, senza perdere l'attività sulle modifiche di orientamento?
@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.
}
}
Questo va bene fino a quando un cambiamento di orientamento succede. Nel progetto di esempio del mortaio, l'ambito dell'attività non viene distrutto nelle modifiche di orientamento. Ciò presumibilmente consente ai presentatori, agli schermi ecc. Di @Singleton di persistere attraverso i cambiamenti di orientamento. Si può vedere questo nel metodo OnDestroy() in attività principale del progetto di esempio:
@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;
}
}
}
Tuttavia, facendo in questo modo significa che la vecchia ObjectGraph persiste attraverso i cambiamenti di orientamento. Ho notato che Mortar.requireActivityScope
non sostituisce il modulo dal vecchio ambito di attività con il nuovo modulo fornito dal nuovo Blueprint. Invece, il grafico dell'oggetto conserva un riferimento al modulo precedente, inclusa l'attività distrutta.
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);
}
}
L'attività di campionamento Mortaio sembra per aggirare il problema non includendo un metodo @Provides Activity
nel modulo principale. Ma il MortarActivityScope
non dovrebbe essere in grado di iniettare un'attività? Qual è il modo migliore per farlo senza perdere tutti gli oggetti singleton (Presenter
oggetti, ecc.) Sul cambio di orientamento?
Molto elegante. L'uso di un Presenter iniettato è un percorso che non avevo mai considerato, ed è molto meno contabile rispetto all'aggiornamento manuale di ogni oggetto che contiene un riferimento all'attività. – weefbellington