public interface ViewWithActivity {
// Using android-gradle-plugin 3.0, which has the desugar step for default methods on interfaces
default Activity getActivity() {
// https://android.googlesource.com/platform/frameworks/support/+/03e0f3daf3c97ee95cd78b2f07bc9c1be05d43db/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java#276
Context context = getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity)context;
}
context = ((ContextWrapper) context).getBaseContext();
}
throw new IllegalStateException("Context does not stem from an activity: " + getContext());
}
}
interface HasViewInjector {
AndroidInjector<View> viewInjector();
}
public abstract DaggerAppCompatWithViewActivityNamingIsFun
extends DaggerAppCompatActivity
implements HasViewInjector {
@Inject DispatchingAndroidInjector<View> viewInjector;
@Override
public AndroidInjector<View> viewInjector() {
return viewInjector;
}
}
@Module
interface ViewInjectionModule {
@Multibinds
abstract Map<Class<? extends View>, AndroidInjector.Factory<? extends View>>
viewInjectorFactories();
}
// ...
@Component(
modules = {
AndroidSupportInjectionModule.class,
ViewInjectionModule.class,
// ...
})
interface AppComponent
public final class ViewInjection {
public static void inject(ViewWithActivity view) {
checkNotNull(view, "view");
Activity activity = view.getActivity();
if (!(application instanceof HasViewInjector)) {
throw new RuntimeException(
String.format(
"%s does not implement %s",
activity.getClass().getCanonicalName(),
HasViewInjector.class.getCanonicalName()));
}
AndroidInjector<View> viewInjector =
((HasViewInjector) activity).viewInjector();
checkNotNull(viewInjector, "%s.viewInjector() returned null", activity.getClass());
viewInjector.inject(view);
}
}
I'm not sure where this should happen yet, perhaps onFinishInflate
or onAttachedToWindow()
?