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