1 /* 2 * Copyright (C) 2017 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.android; 18 19 import android.app.Application; 20 import android.content.ContentProvider; 21 import com.google.errorprone.annotations.ForOverride; 22 import dagger.internal.Beta; 23 import javax.inject.Inject; 24 25 /** 26 * An {@link Application} that injects its members and can be used to inject objects that the 27 * Android framework instantiates, such as Activitys, Fragments, or Services. Injection is performed 28 * in {@link #onCreate()} or the first call to {@link AndroidInjection#inject(ContentProvider)}, 29 * whichever happens first. 30 */ 31 @Beta 32 public abstract class DaggerApplication extends Application implements HasAndroidInjector { 33 @Inject volatile DispatchingAndroidInjector<Object> androidInjector; 34 35 @Override onCreate()36 public void onCreate() { 37 super.onCreate(); 38 injectIfNecessary(); 39 } 40 41 /** 42 * Implementations should return an {@link AndroidInjector} for the concrete {@link 43 * DaggerApplication}. Typically, that injector is a {@link dagger.Component}. 44 */ 45 @ForOverride applicationInjector()46 protected abstract AndroidInjector<? extends DaggerApplication> applicationInjector(); 47 48 /** 49 * Lazily injects the {@link DaggerApplication}'s members. Injection cannot be performed in {@link 50 * Application#onCreate()} since {@link android.content.ContentProvider}s' {@link 51 * android.content.ContentProvider#onCreate() onCreate()} method will be called first and might 52 * need injected members on the application. Injection is not performed in the constructor, as 53 * that may result in members-injection methods being called before the constructor has completed, 54 * allowing for a partially-constructed instance to escape. 55 */ injectIfNecessary()56 private void injectIfNecessary() { 57 if (androidInjector == null) { 58 synchronized (this) { 59 if (androidInjector == null) { 60 @SuppressWarnings("unchecked") 61 AndroidInjector<DaggerApplication> applicationInjector = 62 (AndroidInjector<DaggerApplication>) applicationInjector(); 63 applicationInjector.inject(this); 64 if (androidInjector == null) { 65 throw new IllegalStateException( 66 "The AndroidInjector returned from applicationInjector() did not inject the " 67 + "DaggerApplication"); 68 } 69 } 70 } 71 } 72 } 73 74 @Override androidInjector()75 public AndroidInjector<Object> androidInjector() { 76 // injectIfNecessary should already be called unless we are about to inject a ContentProvider, 77 // which can happen before Application.onCreate() 78 injectIfNecessary(); 79 80 return androidInjector; 81 } 82 } 83