/* * Copyright (C) 2017 The Dagger Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dagger.android; import static android.util.Log.DEBUG; import static dagger.internal.Preconditions.checkNotNull; import android.app.Activity; import android.app.Application; import android.app.Fragment; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ContentProvider; import android.content.Context; import android.util.Log; import dagger.internal.Beta; /** Injects core Android types. */ @Beta public final class AndroidInjection { private static final String TAG = "dagger.android"; /** * Injects {@code activity} if an associated {@link AndroidInjector} implementation can be found, * otherwise throws an {@link IllegalArgumentException}. * * @throws RuntimeException if the {@link Application} doesn't implement {@link * HasAndroidInjector}. */ public static void inject(Activity activity) { checkNotNull(activity, "activity"); Application application = activity.getApplication(); if (!(application instanceof HasAndroidInjector)) { throw new RuntimeException( String.format( "%s does not implement %s", application.getClass().getCanonicalName(), HasAndroidInjector.class.getCanonicalName())); } inject(activity, (HasAndroidInjector) application); } /** * Injects {@code fragment} if an associated {@link AndroidInjector} implementation can be found, * otherwise throws an {@link IllegalArgumentException}. * *
Uses the following algorithm to find the appropriate {@code AndroidInjector
*
*
* If none of them implement {@link HasAndroidInjector}, a {@link IllegalArgumentException} is
* thrown.
*
* @throws IllegalArgumentException if no parent fragment, activity, or application implements
* {@link HasAndroidInjector}.
*/
public static void inject(Fragment fragment) {
checkNotNull(fragment, "fragment");
HasAndroidInjector hasAndroidInjector = findHasAndroidInjectorForFragment(fragment);
if (Log.isLoggable(TAG, DEBUG)) {
Log.d(
TAG,
String.format(
"An injector for %s was found in %s",
fragment.getClass().getCanonicalName(),
hasAndroidInjector.getClass().getCanonicalName()));
}
inject(fragment, hasAndroidInjector);
}
private static HasAndroidInjector findHasAndroidInjectorForFragment(Fragment fragment) {
Fragment parentFragment = fragment;
while ((parentFragment = parentFragment.getParentFragment()) != null) {
if (parentFragment instanceof HasAndroidInjector) {
return (HasAndroidInjector) parentFragment;
}
}
Activity activity = fragment.getActivity();
if (activity instanceof HasAndroidInjector) {
return (HasAndroidInjector) activity;
}
if (activity.getApplication() instanceof HasAndroidInjector) {
return (HasAndroidInjector) activity.getApplication();
}
throw new IllegalArgumentException(
String.format("No injector was found for %s", fragment.getClass().getCanonicalName()));
}
/**
* Injects {@code service} if an associated {@link AndroidInjector} implementation can be found,
* otherwise throws an {@link IllegalArgumentException}.
*
* @throws RuntimeException if the {@link Application} doesn't implement {@link
* HasAndroidInjector}.
*/
public static void inject(Service service) {
checkNotNull(service, "service");
Application application = service.getApplication();
if (!(application instanceof HasAndroidInjector)) {
throw new RuntimeException(
String.format(
"%s does not implement %s",
application.getClass().getCanonicalName(),
HasAndroidInjector.class.getCanonicalName()));
}
inject(service, (HasAndroidInjector) application);
}
/**
* Injects {@code broadcastReceiver} if an associated {@link AndroidInjector} implementation can
* be found, otherwise throws an {@link IllegalArgumentException}.
*
* @throws RuntimeException if the {@link Application} from {@link
* Context#getApplicationContext()} doesn't implement {@link HasAndroidInjector}.
*/
public static void inject(BroadcastReceiver broadcastReceiver, Context context) {
checkNotNull(broadcastReceiver, "broadcastReceiver");
checkNotNull(context, "context");
Application application = (Application) context.getApplicationContext();
if (!(application instanceof HasAndroidInjector)) {
throw new RuntimeException(
String.format(
"%s does not implement %s",
application.getClass().getCanonicalName(),
HasAndroidInjector.class.getCanonicalName()));
}
inject(broadcastReceiver, (HasAndroidInjector) application);
}
/**
* Injects {@code contentProvider} if an associated {@link AndroidInjector} implementation can be
* found, otherwise throws an {@link IllegalArgumentException}.
*
* @throws RuntimeException if the {@link Application} doesn't implement {@link
* HasAndroidInjector}.
*/
public static void inject(ContentProvider contentProvider) {
checkNotNull(contentProvider, "contentProvider");
Application application = (Application) contentProvider.getContext().getApplicationContext();
if (!(application instanceof HasAndroidInjector)) {
throw new RuntimeException(
String.format(
"%s does not implement %s",
application.getClass().getCanonicalName(),
HasAndroidInjector.class.getCanonicalName()));
}
inject(contentProvider, (HasAndroidInjector) application);
}
private static void inject(Object target, HasAndroidInjector hasAndroidInjector) {
AndroidInjector