I am reading the source code for Dagger2 Component Scopes Test on GitHub, and I've seen a "custom scope" defined for activities called @ActivityScope
, but I've seen it in other projects including the 4-module CleanArchitecture that has its @PerActivity
scope.
But literally, the code for the @ActivityScope
annotation is the following:
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 { }
And it is "magically" usable in Modules:
@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(); } }
Or the CleanArchitecture example:
@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; } }
I can clearly see that this has to do with JSR-330 custom scopes, but I really don't understand what exactly is happening here to make it so that this code enables the given module and/or what is provided by a given module to depend on the actual Activity
lifecycle, and for there to exist only a single instance but only if that given activity is active.
The docs say this:
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.
It says to look at the Component docs page, but that gives me 404. I also saw this, but...
May I ask for some help in clarifying why specifying this custom scope magically makes Activity-level scopes
work without an issue?
(The answer is, a subscope can receive dependencies from its superscope, and a subscope exists as long as the component does. And that you need to specify the scopes on your modules, and you need to specify your component dependencies to subscope one superscope.)