xref: /aosp_15_r20/external/dagger2/java/dagger/android/DaggerApplication.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
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