Dagger2 Benutzerdefinierte Bereiche : Wie custom-Bereiche (@ActivityScope) tatsächlich funktionieren?
Lese ich den Quellcode für Dagger2 Komponente Bereiche Test auf GitHub, und ich habe gesehen, einem "benutzerdefinierten Bereich" definiert, die für die Tätigkeiten genannt @ActivityScope
, aber ich habe gesehen, dass es in anderen Projekten, wie der 4-Modul CleanArchitecture, der hat seine @PerActivity
Umfang.
Aber wörtlich, den code für die @ActivityScope
Anmerkung ist die folgende:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
/**
* Created by joesteele on 2/15/15.
*/
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
Und es ist "magisch" verwendbar in den Modulen:
@Module
public class ActivityModule {
@Provides @ActivityScope Picasso providePicasso(ComponentTest app, OkHttpClient client) {
return new Picasso.Builder(app)
.downloader(new OkHttpDownloader(client))
.listener(new Picasso.Listener() {
@Override public void onImageLoadFailed(Picasso picasso, Uri uri, Exception e) {
Log.e("Picasso", "Failed to load image: " + uri.toString(), e);
}
})
.build();
}
}
Oder die CleanArchitecture Beispiel:
@Scope
@Retention(RUNTIME)
public @interface PerActivity {}
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
//Exposed to sub-graphs.
Activity activity();
}
@Module
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
/**
* Expose the activity to dependents in the graph.
*/
@Provides @PerActivity Activity activity() {
return this.activity;
}
}
Kann ich deutlich sehen, dass dies hat zu tun mit JSR-330 benutzerdefinierte Bereiche, aber ich wirklich nicht verstehen, was genau hier passiert, es so zu machen, dass dieser code ermöglicht das angegebene Modul und/oder das, was ein bestimmtes Modul angewiesen auf die tatsächliche Activity
Lebenszyklus, und es existiert nur eine einzige Instanz, aber nur, wenn das gegebene Aktivität aktiv ist.
Die docs sagen:
Scope
Dagger 1 only supported a single scope: @Singleton.
Dagger 2 allows users to any well-formed scope annotation.
The Component docs describe the details of
how to properly apply scope to a component.
Sagt er zu Blick auf die Komponente docs-Seite, aber das gibt mir 404. Ich sah auch diese, aber...
Darf ich Fragen, für etwas Hilfe bei der Klärung, warum die Angabe dieser benutzerdefinierten Bereich magisch macht Activity-level scopes
arbeiten, ohne ein Problem?
(Die Antwort ist, ein subscope erhalten können Abhängigkeiten von seiner superscope, und ein subscope besteht, solange die Komponente tut. Und, dass Sie müssen angeben, dass die Bereiche, die auf Ihre Module, und Sie müssen angeben, dass Ihre Komponente Abhängigkeiten zu subscope eine superscope.)
- github.com/google/dagger/tree/master/examples/... hmm...
- Hier ist der richtige link zu den Komponenten-docs-Seite für alle, die dies Lesen: google.github.io/dagger/api/2.0/dagger/Component.html
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eigentlich gibt es keine Magie. Benutzerdefinierten Bereich Anmerkungen sind nur Anmerkungen. Sie können einen beliebigen Namen haben.
Erste Funktion der Bereiche ist ein Weg, zu sagen, Dolch compiler die Bereiche sind, dürfen innerhalb Gültigkeitsbereich Komponente. Das ist, warum mit
@ActivityScope
Abhängigkeit im nicht-@ActivityScope
Komponente wird Feuer zu einem Kompilierungsfehler.In der Tat-Komponenten können erklären, viele Bereiche (z.B.
@ActivityScope
und@UiScope
) und Dolch behandeln Sie beide als Rahmen - es nennt sich scope-aliasing. Es ist zum Beispiel nützlich in multi-module-Projekten - wenn man Gradle-Modul definiert einen Bereich mit seinem Dolch Module und andere Gradle-Modul definiert einen anderen Bereich, während beide von Ihnen können als Einzelzimmer genutzt werden alias-Umfang in einigen Dritten Gradle-Modul definiert Dolch Komponente.Zweite Funktion ist die Begrenzung der Anzahl der Instanzen darf innerhalb Gültigkeitsbereich Komponente. Es gibt mehrere Arten von Bereichen unterstützt:
Ohne bereichseinschränkung - wenn keine annotation deklariert. Ohne bereichseinschränkung Abhängigkeit haben einfach
Provider
generiert ohne Zwischenspeicherung und jede Instanz der Abhängigkeit geschaffen Komponente wird neu für jede neue Injektion (wie im Konstruktor, oder in-Modul-Bestimmung-Methode, oder einfach nur ein Feld).Benutzerdefinierten Bereich z.B.
@ActivityScope
annotation definiert mit@javax.inject.Scope
annotation - Abhängigkeiten erklärt, dass der Umfang mit ZwischenspeicherungProvider
mit double-check lock erstellt wird und nur eine einzige Instanz erstellt werden, für die es innerhalb der Komponente deklariert mit dem gleichen Umfang und seiner Entstehung wird thread-sicher. Beachten Sie, dass für jede Instanz der Komponente selbst neue Instanz der Abhängigkeit geschaffen werden.Wiederverwendbare Bereich - erklärt mit
@dagger.Reusable
annotation - Abhängigkeiten erklärt, dass Umfang können geteilt werden zwischen den verschiedenen Komponenten durch gemeinsame übergeordnete Komponente und ZwischenspeicherungProvider
mit single-check lock erzeugt. Es ist nützlich, wenn Abhängigkeit nicht notwendigerweise müssen einzelne Instanz kann aber freigegeben werden, für höhere Leistung (weniger Zuweisungen) in Einzel-Komponente oder zwischen Komponenten.Für mehr info auf, wie die Bereiche Arbeit finden user ' s guide und Dolch generierten code.
Wie definieren Sie den tatsächlichen Umfang ist Ihr Vorrecht. Definieren Sie die livecycle Ihrer Umfang Komponente, wenn es erstellt wurde, und wenn es zerstört wird - das ist Ihr Umfang. E. g.
@ActivityScope
ist gebunden an die Aktivität livecycle und definiert so:So gibt es keine Magie. Definieren Sie Ihre Bereiche, die durch die Semantik der Verwendung von Ihnen.
Vielleicht finden Sie auch nützliche diese Antwort und diese Beispiele.
BEARBEITEN 14.10.2018 Erweitert auf die Bereiche der Funktionen und Typen, um Mehrdeutigkeit zu vermeiden, die in früheren Antwort.
component = null
?onRetainCustomNonConfigurationInstance()
oder einem Mörser Umfang! Oder einfach nur speichern Sie es in einemMap<K,V>
imApplication
aber glaube nicht, dass über Fragmente!@PerActivity
in a die Methode gleichen Zeit.@ActivityScope
... so verstehe ich es jedenfalls, ich bin sehr neu auf Dolch 2 - wenn jemand das widerlegen, was ich sage, bitte!Es ist erwähnenswert, dass offenbar Dagger2 erstellt eine einzelne Instanz pro scoped-Anbieter in einem Modul pro Komponente.
So, in Reihenfolge zu get ein scoped-Anbieter in einem Modul, müssen Sie den Bereich für die Modul-Anbieter-Methode.
BEARBEITEN START: obwohl in der Regel, brauchen Sie nicht zu instanziieren, Ihre eigenen Implementierungen innerhalb Ihrer Module, so kann man eigentlich nur dazu:
EDIT ENDE
Danach finden Kirill Antwort; im Grunde ein "Rahmen", indem Sie nur sich selbst feststellt, dass es einem anderen Bereich als der andere. Verwenden von Komponenten-Abhängigkeiten (oder Teilkomponenten) erstellt eine subscope.
Einer Komponente verlassen können, nur auf einem anderen Gültigkeitsbereich Komponente.
@YourScope
einmal auf der Oberseite des @ - Modul ist gleich zu schreiben@YourScope
für jede Methode separat innen-Modul richtig?Kirill Boyarshinov
zur Verfügung gestellt, die eine richtige Antwort zu. Sie akzeptieren Ihre eigenen Antworten.Scope annotations serve as a tool for static analysis of dependencies
" ist nicht wirklich wahr. Hinzufügen eines scope auf einen@Provides
Methode macht es generieren scoped-provider und diese Unterscheidung ist sehr wichtig; wenn es wahr ist, dass die Bauteile selbst erforderlich ist es für die Validierung und die Verwaltung des Lebenszyklus selbst. Aber scopes wirklich ein bisschen mehr als das. Auch ich sollte wohl erwähnen Gültigkeitsbereich der Klasse mit@Inject
Konstruktor in dieser Antwort, die für die Vollendung Willen. Auch habe ich keine Punkte bekomme für das akzeptieren meiner Antwort, fühlen Sie sich frei, um upvote anderen auch Antworten.