1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2020 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.hilt.android; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 20*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat; 21*f585d8a3SJacky Wang import static java.lang.annotation.RetentionPolicy.RUNTIME; 22*f585d8a3SJacky Wang import static org.junit.Assert.fail; 23*f585d8a3SJacky Wang 24*f585d8a3SJacky Wang import android.annotation.TargetApi; 25*f585d8a3SJacky Wang import android.app.Activity; 26*f585d8a3SJacky Wang import android.app.IntentService; 27*f585d8a3SJacky Wang import android.app.Service; 28*f585d8a3SJacky Wang import android.content.BroadcastReceiver; 29*f585d8a3SJacky Wang import android.content.Context; 30*f585d8a3SJacky Wang import android.content.Intent; 31*f585d8a3SJacky Wang import android.os.Build; 32*f585d8a3SJacky Wang import android.os.Bundle; 33*f585d8a3SJacky Wang import android.os.IBinder; 34*f585d8a3SJacky Wang import androidx.fragment.app.Fragment; 35*f585d8a3SJacky Wang import androidx.fragment.app.FragmentActivity; 36*f585d8a3SJacky Wang import android.util.AttributeSet; 37*f585d8a3SJacky Wang import android.widget.LinearLayout; 38*f585d8a3SJacky Wang import androidx.test.ext.junit.runners.AndroidJUnit4; 39*f585d8a3SJacky Wang import dagger.Module; 40*f585d8a3SJacky Wang import dagger.Provides; 41*f585d8a3SJacky Wang import dagger.hilt.InstallIn; 42*f585d8a3SJacky Wang import dagger.hilt.android.components.ActivityComponent; 43*f585d8a3SJacky Wang import dagger.hilt.android.components.FragmentComponent; 44*f585d8a3SJacky Wang import dagger.hilt.android.components.ServiceComponent; 45*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidRule; 46*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidTest; 47*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltTestApplication; 48*f585d8a3SJacky Wang import dagger.hilt.components.SingletonComponent; 49*f585d8a3SJacky Wang import java.lang.annotation.ElementType; 50*f585d8a3SJacky Wang import java.lang.annotation.Retention; 51*f585d8a3SJacky Wang import java.lang.annotation.Target; 52*f585d8a3SJacky Wang import java.util.concurrent.atomic.AtomicLong; 53*f585d8a3SJacky Wang import javax.inject.Inject; 54*f585d8a3SJacky Wang import javax.inject.Qualifier; 55*f585d8a3SJacky Wang import javax.inject.Singleton; 56*f585d8a3SJacky Wang import org.junit.Before; 57*f585d8a3SJacky Wang import org.junit.Rule; 58*f585d8a3SJacky Wang import org.junit.Test; 59*f585d8a3SJacky Wang import org.junit.runner.RunWith; 60*f585d8a3SJacky Wang import org.robolectric.Robolectric; 61*f585d8a3SJacky Wang import org.robolectric.android.controller.ActivityController; 62*f585d8a3SJacky Wang import org.robolectric.annotation.Config; 63*f585d8a3SJacky Wang 64*f585d8a3SJacky Wang @HiltAndroidTest 65*f585d8a3SJacky Wang @RunWith(AndroidJUnit4.class) 66*f585d8a3SJacky Wang // Robolectric requires Java9 to run API 29 and above, so use API 28 instead 67*f585d8a3SJacky Wang @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class) 68*f585d8a3SJacky Wang public final class InjectionTest { 69*f585d8a3SJacky Wang private static final String APP_BINDING = "APP_BINDING"; 70*f585d8a3SJacky Wang private static final String ACTIVITY_BINDING = "ACTIVIY_BINDING"; 71*f585d8a3SJacky Wang private static final String FRAGMENT_BINDING = "FRAGMENT_BINDING"; 72*f585d8a3SJacky Wang private static final String SERVICE_BINDING = "SERVICE_BINDING"; 73*f585d8a3SJacky Wang 74*f585d8a3SJacky Wang @Retention(RUNTIME) 75*f585d8a3SJacky Wang @Qualifier 76*f585d8a3SJacky Wang @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 77*f585d8a3SJacky Wang @interface ApplicationLevel {} 78*f585d8a3SJacky Wang 79*f585d8a3SJacky Wang @Retention(RUNTIME) 80*f585d8a3SJacky Wang @Qualifier 81*f585d8a3SJacky Wang @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 82*f585d8a3SJacky Wang @interface ActivityLevel {} 83*f585d8a3SJacky Wang 84*f585d8a3SJacky Wang @Retention(RUNTIME) 85*f585d8a3SJacky Wang @Qualifier 86*f585d8a3SJacky Wang @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 87*f585d8a3SJacky Wang @interface FragmentLevel {} 88*f585d8a3SJacky Wang 89*f585d8a3SJacky Wang @Retention(RUNTIME) 90*f585d8a3SJacky Wang @Qualifier 91*f585d8a3SJacky Wang @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 92*f585d8a3SJacky Wang @interface ServiceLevel {} 93*f585d8a3SJacky Wang 94*f585d8a3SJacky Wang /** Application level bindings */ 95*f585d8a3SJacky Wang @Module 96*f585d8a3SJacky Wang @InstallIn(SingletonComponent.class) 97*f585d8a3SJacky Wang static final class AppModule { 98*f585d8a3SJacky Wang @Provides 99*f585d8a3SJacky Wang @ApplicationLevel providesAppBinding()100*f585d8a3SJacky Wang static String providesAppBinding() { 101*f585d8a3SJacky Wang return APP_BINDING; 102*f585d8a3SJacky Wang } 103*f585d8a3SJacky Wang 104*f585d8a3SJacky Wang @Provides 105*f585d8a3SJacky Wang @Singleton provideCounter()106*f585d8a3SJacky Wang static AtomicLong provideCounter() { 107*f585d8a3SJacky Wang return new AtomicLong(); 108*f585d8a3SJacky Wang } 109*f585d8a3SJacky Wang 110*f585d8a3SJacky Wang @Provides provideCount(AtomicLong counter)111*f585d8a3SJacky Wang static Long provideCount(AtomicLong counter) { 112*f585d8a3SJacky Wang return counter.incrementAndGet(); 113*f585d8a3SJacky Wang } 114*f585d8a3SJacky Wang } 115*f585d8a3SJacky Wang 116*f585d8a3SJacky Wang /** Activity level bindings */ 117*f585d8a3SJacky Wang @Module 118*f585d8a3SJacky Wang @InstallIn(ActivityComponent.class) 119*f585d8a3SJacky Wang static final class ActivityModule { 120*f585d8a3SJacky Wang @Provides 121*f585d8a3SJacky Wang @ActivityLevel providesActivityBinding()122*f585d8a3SJacky Wang static String providesActivityBinding() { 123*f585d8a3SJacky Wang return ACTIVITY_BINDING; 124*f585d8a3SJacky Wang } 125*f585d8a3SJacky Wang } 126*f585d8a3SJacky Wang 127*f585d8a3SJacky Wang /** Fragment level bindings */ 128*f585d8a3SJacky Wang @Module 129*f585d8a3SJacky Wang @InstallIn(FragmentComponent.class) 130*f585d8a3SJacky Wang static final class FragmentModule { 131*f585d8a3SJacky Wang @Provides 132*f585d8a3SJacky Wang @FragmentLevel providesFragmentBinding()133*f585d8a3SJacky Wang static String providesFragmentBinding() { 134*f585d8a3SJacky Wang return FRAGMENT_BINDING; 135*f585d8a3SJacky Wang } 136*f585d8a3SJacky Wang } 137*f585d8a3SJacky Wang 138*f585d8a3SJacky Wang /** Service level bindings */ 139*f585d8a3SJacky Wang @Module 140*f585d8a3SJacky Wang @InstallIn(ServiceComponent.class) 141*f585d8a3SJacky Wang static final class ServiceModule { 142*f585d8a3SJacky Wang @Provides 143*f585d8a3SJacky Wang @ServiceLevel providesServiceBinding()144*f585d8a3SJacky Wang static String providesServiceBinding() { 145*f585d8a3SJacky Wang return SERVICE_BINDING; 146*f585d8a3SJacky Wang } 147*f585d8a3SJacky Wang } 148*f585d8a3SJacky Wang 149*f585d8a3SJacky Wang /** Hilt Activity */ 150*f585d8a3SJacky Wang @AndroidEntryPoint(FragmentActivity.class) 151*f585d8a3SJacky Wang public static final class TestActivity extends Hilt_InjectionTest_TestActivity { 152*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 153*f585d8a3SJacky Wang @Inject @ActivityLevel String activityBinding; 154*f585d8a3SJacky Wang boolean onCreateCalled; 155*f585d8a3SJacky Wang 156*f585d8a3SJacky Wang @Override onCreate(Bundle onSavedInstanceState)157*f585d8a3SJacky Wang public void onCreate(Bundle onSavedInstanceState) { 158*f585d8a3SJacky Wang assertThat(appBinding).isNull(); 159*f585d8a3SJacky Wang assertThat(activityBinding).isNull(); 160*f585d8a3SJacky Wang 161*f585d8a3SJacky Wang super.onCreate(onSavedInstanceState); 162*f585d8a3SJacky Wang 163*f585d8a3SJacky Wang assertThat(appBinding).isEqualTo(APP_BINDING); 164*f585d8a3SJacky Wang assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING); 165*f585d8a3SJacky Wang 166*f585d8a3SJacky Wang onCreateCalled = true; 167*f585d8a3SJacky Wang } 168*f585d8a3SJacky Wang } 169*f585d8a3SJacky Wang 170*f585d8a3SJacky Wang /** Non-Hilt Activity */ 171*f585d8a3SJacky Wang public static final class NonHiltActivity extends FragmentActivity {} 172*f585d8a3SJacky Wang 173*f585d8a3SJacky Wang /** Hilt Fragment */ 174*f585d8a3SJacky Wang @AndroidEntryPoint(Fragment.class) 175*f585d8a3SJacky Wang public static final class TestFragment extends Hilt_InjectionTest_TestFragment { 176*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 177*f585d8a3SJacky Wang @Inject @ActivityLevel String activityBinding; 178*f585d8a3SJacky Wang @Inject @FragmentLevel String fragmentBinding; 179*f585d8a3SJacky Wang boolean onAttachContextCalled; 180*f585d8a3SJacky Wang boolean onAttachActivityCalled; 181*f585d8a3SJacky Wang 182*f585d8a3SJacky Wang @Override onAttach(Context context)183*f585d8a3SJacky Wang public void onAttach(Context context) { 184*f585d8a3SJacky Wang preInjectionAssert(); 185*f585d8a3SJacky Wang super.onAttach(context); 186*f585d8a3SJacky Wang postInjectionAssert(); 187*f585d8a3SJacky Wang onAttachContextCalled = true; 188*f585d8a3SJacky Wang } 189*f585d8a3SJacky Wang 190*f585d8a3SJacky Wang @Override onAttach(Activity activity)191*f585d8a3SJacky Wang public void onAttach(Activity activity) { 192*f585d8a3SJacky Wang preInjectionAssert(); 193*f585d8a3SJacky Wang super.onAttach(activity); 194*f585d8a3SJacky Wang postInjectionAssert(); 195*f585d8a3SJacky Wang onAttachActivityCalled = true; 196*f585d8a3SJacky Wang } 197*f585d8a3SJacky Wang preInjectionAssert()198*f585d8a3SJacky Wang private void preInjectionAssert() { 199*f585d8a3SJacky Wang assertThat(appBinding).isNull(); 200*f585d8a3SJacky Wang assertThat(activityBinding).isNull(); 201*f585d8a3SJacky Wang assertThat(fragmentBinding).isNull(); 202*f585d8a3SJacky Wang } 203*f585d8a3SJacky Wang postInjectionAssert()204*f585d8a3SJacky Wang private void postInjectionAssert() { 205*f585d8a3SJacky Wang assertThat(appBinding).isEqualTo(APP_BINDING); 206*f585d8a3SJacky Wang assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING); 207*f585d8a3SJacky Wang assertThat(fragmentBinding).isEqualTo(FRAGMENT_BINDING); 208*f585d8a3SJacky Wang } 209*f585d8a3SJacky Wang } 210*f585d8a3SJacky Wang 211*f585d8a3SJacky Wang /** Non-Hilt Fragment */ 212*f585d8a3SJacky Wang public static final class NonHiltFragment extends Fragment {} 213*f585d8a3SJacky Wang 214*f585d8a3SJacky Wang /** Hilt extends parameterized fragment. */ 215*f585d8a3SJacky Wang @AndroidEntryPoint(ParameterizedFragment.class) 216*f585d8a3SJacky Wang public static final class TestParameterizedFragment 217*f585d8a3SJacky Wang extends Hilt_InjectionTest_TestParameterizedFragment<Integer> { 218*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 219*f585d8a3SJacky Wang @Inject @ActivityLevel String activityBinding; 220*f585d8a3SJacky Wang @Inject @FragmentLevel String fragmentBinding; 221*f585d8a3SJacky Wang boolean onAttachContextCalled; 222*f585d8a3SJacky Wang boolean onAttachActivityCalled; 223*f585d8a3SJacky Wang 224*f585d8a3SJacky Wang @Override onAttach(Context context)225*f585d8a3SJacky Wang public void onAttach(Context context) { 226*f585d8a3SJacky Wang preInjectionAssert(); 227*f585d8a3SJacky Wang super.onAttach(context); 228*f585d8a3SJacky Wang postInjectionAssert(); 229*f585d8a3SJacky Wang onAttachContextCalled = true; 230*f585d8a3SJacky Wang } 231*f585d8a3SJacky Wang 232*f585d8a3SJacky Wang @Override onAttach(Activity activity)233*f585d8a3SJacky Wang public void onAttach(Activity activity) { 234*f585d8a3SJacky Wang preInjectionAssert(); 235*f585d8a3SJacky Wang super.onAttach(activity); 236*f585d8a3SJacky Wang postInjectionAssert(); 237*f585d8a3SJacky Wang onAttachActivityCalled = true; 238*f585d8a3SJacky Wang } 239*f585d8a3SJacky Wang preInjectionAssert()240*f585d8a3SJacky Wang private void preInjectionAssert() { 241*f585d8a3SJacky Wang assertThat(appBinding).isNull(); 242*f585d8a3SJacky Wang assertThat(activityBinding).isNull(); 243*f585d8a3SJacky Wang assertThat(fragmentBinding).isNull(); 244*f585d8a3SJacky Wang } 245*f585d8a3SJacky Wang postInjectionAssert()246*f585d8a3SJacky Wang private void postInjectionAssert() { 247*f585d8a3SJacky Wang assertThat(appBinding).isEqualTo(APP_BINDING); 248*f585d8a3SJacky Wang assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING); 249*f585d8a3SJacky Wang assertThat(fragmentBinding).isEqualTo(FRAGMENT_BINDING); 250*f585d8a3SJacky Wang } 251*f585d8a3SJacky Wang } 252*f585d8a3SJacky Wang 253*f585d8a3SJacky Wang /** Non-Hilt parameterized fragment */ 254*f585d8a3SJacky Wang public static class ParameterizedFragment<T> extends Fragment {} 255*f585d8a3SJacky Wang 256*f585d8a3SJacky Wang /** Hilt View */ 257*f585d8a3SJacky Wang @AndroidEntryPoint(LinearLayout.class) 258*f585d8a3SJacky Wang public static final class TestView extends Hilt_InjectionTest_TestView { 259*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 260*f585d8a3SJacky Wang @Inject @ActivityLevel String activityBinding; 261*f585d8a3SJacky Wang TestView(Context context)262*f585d8a3SJacky Wang TestView(Context context) { 263*f585d8a3SJacky Wang super(context); 264*f585d8a3SJacky Wang } 265*f585d8a3SJacky Wang TestView(Context context, AttributeSet attrs)266*f585d8a3SJacky Wang TestView(Context context, AttributeSet attrs) { 267*f585d8a3SJacky Wang super(context, attrs); 268*f585d8a3SJacky Wang } 269*f585d8a3SJacky Wang TestView(Context context, AttributeSet attrs, int defStyleAttr)270*f585d8a3SJacky Wang TestView(Context context, AttributeSet attrs, int defStyleAttr) { 271*f585d8a3SJacky Wang super(context, attrs, defStyleAttr); 272*f585d8a3SJacky Wang } 273*f585d8a3SJacky Wang 274*f585d8a3SJacky Wang @TargetApi(21) TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)275*f585d8a3SJacky Wang TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 276*f585d8a3SJacky Wang super(context, attrs, defStyleAttr, defStyleRes); 277*f585d8a3SJacky Wang } 278*f585d8a3SJacky Wang } 279*f585d8a3SJacky Wang 280*f585d8a3SJacky Wang /** Hilt View (With Fragment bindings) */ 281*f585d8a3SJacky Wang @WithFragmentBindings 282*f585d8a3SJacky Wang @AndroidEntryPoint(LinearLayout.class) 283*f585d8a3SJacky Wang public static final class TestViewWithFragmentBindings 284*f585d8a3SJacky Wang extends Hilt_InjectionTest_TestViewWithFragmentBindings { 285*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 286*f585d8a3SJacky Wang @Inject @ActivityLevel String activityBinding; 287*f585d8a3SJacky Wang @Inject @FragmentLevel String fragmentBinding; 288*f585d8a3SJacky Wang TestViewWithFragmentBindings(Context context)289*f585d8a3SJacky Wang TestViewWithFragmentBindings(Context context) { 290*f585d8a3SJacky Wang super(context); 291*f585d8a3SJacky Wang } 292*f585d8a3SJacky Wang } 293*f585d8a3SJacky Wang 294*f585d8a3SJacky Wang @AndroidEntryPoint(Service.class) 295*f585d8a3SJacky Wang public static final class TestService extends Hilt_InjectionTest_TestService { 296*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 297*f585d8a3SJacky Wang @Inject @ServiceLevel String serviceBinding; 298*f585d8a3SJacky Wang 299*f585d8a3SJacky Wang @Override onBind(Intent intent)300*f585d8a3SJacky Wang public IBinder onBind(Intent intent) { 301*f585d8a3SJacky Wang return null; 302*f585d8a3SJacky Wang } 303*f585d8a3SJacky Wang } 304*f585d8a3SJacky Wang 305*f585d8a3SJacky Wang @AndroidEntryPoint(IntentService.class) 306*f585d8a3SJacky Wang public static final class TestIntentService extends Hilt_InjectionTest_TestIntentService { 307*f585d8a3SJacky Wang private static final String NAME = "TestIntentServiceName"; 308*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 309*f585d8a3SJacky Wang @Inject @ServiceLevel String serviceBinding; 310*f585d8a3SJacky Wang TestIntentService()311*f585d8a3SJacky Wang TestIntentService() { 312*f585d8a3SJacky Wang super(NAME); 313*f585d8a3SJacky Wang } 314*f585d8a3SJacky Wang 315*f585d8a3SJacky Wang @Override onHandleIntent(Intent intent)316*f585d8a3SJacky Wang public void onHandleIntent(Intent intent) {} 317*f585d8a3SJacky Wang } 318*f585d8a3SJacky Wang 319*f585d8a3SJacky Wang @AndroidEntryPoint(BroadcastReceiver.class) 320*f585d8a3SJacky Wang public static final class TestBroadcastReceiver extends Hilt_InjectionTest_TestBroadcastReceiver { 321*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 322*f585d8a3SJacky Wang Intent lastIntent = null; 323*f585d8a3SJacky Wang 324*f585d8a3SJacky Wang @Override onReceive(Context context, Intent intent)325*f585d8a3SJacky Wang public void onReceive(Context context, Intent intent) { 326*f585d8a3SJacky Wang super.onReceive(context, intent); 327*f585d8a3SJacky Wang lastIntent = intent; 328*f585d8a3SJacky Wang } 329*f585d8a3SJacky Wang } 330*f585d8a3SJacky Wang 331*f585d8a3SJacky Wang @AndroidEntryPoint(BaseBroadcastReceiver.class) 332*f585d8a3SJacky Wang public static final class TestBroadcastReceiverWithBaseImplementingOnReceive 333*f585d8a3SJacky Wang extends Hilt_InjectionTest_TestBroadcastReceiverWithBaseImplementingOnReceive { 334*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 335*f585d8a3SJacky Wang Intent baseLastIntent = null; 336*f585d8a3SJacky Wang 337*f585d8a3SJacky Wang @Override onReceive(Context context, Intent intent)338*f585d8a3SJacky Wang public void onReceive(Context context, Intent intent) { 339*f585d8a3SJacky Wang super.onReceive(context, intent); 340*f585d8a3SJacky Wang baseLastIntent = intent; 341*f585d8a3SJacky Wang } 342*f585d8a3SJacky Wang } 343*f585d8a3SJacky Wang 344*f585d8a3SJacky Wang abstract static class BaseBroadcastReceiver extends BroadcastReceiver { 345*f585d8a3SJacky Wang Intent lastIntent = null; 346*f585d8a3SJacky Wang 347*f585d8a3SJacky Wang @Override onReceive(Context context, Intent intent)348*f585d8a3SJacky Wang public void onReceive(Context context, Intent intent) { 349*f585d8a3SJacky Wang lastIntent = intent; 350*f585d8a3SJacky Wang } 351*f585d8a3SJacky Wang } 352*f585d8a3SJacky Wang 353*f585d8a3SJacky Wang @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); 354*f585d8a3SJacky Wang 355*f585d8a3SJacky Wang @Inject @ApplicationLevel String appBinding; 356*f585d8a3SJacky Wang 357*f585d8a3SJacky Wang @Before setup()358*f585d8a3SJacky Wang public void setup() { 359*f585d8a3SJacky Wang rule.inject(); 360*f585d8a3SJacky Wang } 361*f585d8a3SJacky Wang 362*f585d8a3SJacky Wang @Test testAppInjection()363*f585d8a3SJacky Wang public void testAppInjection() throws Exception { 364*f585d8a3SJacky Wang assertThat(appBinding).isEqualTo(APP_BINDING); 365*f585d8a3SJacky Wang } 366*f585d8a3SJacky Wang 367*f585d8a3SJacky Wang @Test testActivityInjection()368*f585d8a3SJacky Wang public void testActivityInjection() throws Exception { 369*f585d8a3SJacky Wang ActivityController<TestActivity> controller = Robolectric.buildActivity(TestActivity.class); 370*f585d8a3SJacky Wang 371*f585d8a3SJacky Wang assertThat(controller.get().onCreateCalled).isFalse(); 372*f585d8a3SJacky Wang controller.create(); 373*f585d8a3SJacky Wang assertThat(controller.get().onCreateCalled).isTrue(); 374*f585d8a3SJacky Wang } 375*f585d8a3SJacky Wang 376*f585d8a3SJacky Wang @Test testFragmentInjection()377*f585d8a3SJacky Wang public void testFragmentInjection() throws Exception { 378*f585d8a3SJacky Wang TestFragment fragment = new TestFragment(); 379*f585d8a3SJacky Wang assertThat(fragment.onAttachContextCalled).isFalse(); 380*f585d8a3SJacky Wang assertThat(fragment.onAttachActivityCalled).isFalse(); 381*f585d8a3SJacky Wang setupFragment(TestActivity.class, fragment); 382*f585d8a3SJacky Wang assertThat(fragment.onAttachContextCalled).isTrue(); 383*f585d8a3SJacky Wang assertThat(fragment.onAttachActivityCalled).isTrue(); 384*f585d8a3SJacky Wang } 385*f585d8a3SJacky Wang 386*f585d8a3SJacky Wang @Test testParameterizedFragmentInjection()387*f585d8a3SJacky Wang public void testParameterizedFragmentInjection() throws Exception { 388*f585d8a3SJacky Wang TestParameterizedFragment fragment = new TestParameterizedFragment(); 389*f585d8a3SJacky Wang assertThat(fragment.onAttachContextCalled).isFalse(); 390*f585d8a3SJacky Wang assertThat(fragment.onAttachActivityCalled).isFalse(); 391*f585d8a3SJacky Wang setupFragment(TestActivity.class, fragment); 392*f585d8a3SJacky Wang assertThat(fragment.onAttachContextCalled).isTrue(); 393*f585d8a3SJacky Wang assertThat(fragment.onAttachActivityCalled).isTrue(); 394*f585d8a3SJacky Wang } 395*f585d8a3SJacky Wang 396*f585d8a3SJacky Wang @Test testViewNoFragmentBindingsWithActivity()397*f585d8a3SJacky Wang public void testViewNoFragmentBindingsWithActivity() throws Exception { 398*f585d8a3SJacky Wang TestActivity activity = Robolectric.setupActivity(TestActivity.class); 399*f585d8a3SJacky Wang TestView view = new TestView(activity); 400*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 401*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 402*f585d8a3SJacky Wang } 403*f585d8a3SJacky Wang 404*f585d8a3SJacky Wang @Test testViewNoFragmentBindingsWithFragment()405*f585d8a3SJacky Wang public void testViewNoFragmentBindingsWithFragment() throws Exception { 406*f585d8a3SJacky Wang TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); 407*f585d8a3SJacky Wang TestView view = new TestView(fragment.getContext()); 408*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 409*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 410*f585d8a3SJacky Wang } 411*f585d8a3SJacky Wang 412*f585d8a3SJacky Wang @Test testViewNoFragmentBindingsWithFragment_secondConstructor()413*f585d8a3SJacky Wang public void testViewNoFragmentBindingsWithFragment_secondConstructor() throws Exception { 414*f585d8a3SJacky Wang TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); 415*f585d8a3SJacky Wang TestView view = new TestView(fragment.getContext(), /* attrs= */ null); 416*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 417*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 418*f585d8a3SJacky Wang } 419*f585d8a3SJacky Wang 420*f585d8a3SJacky Wang @Test testViewNoFragmentBindingsWithFragment_thirdConstructor()421*f585d8a3SJacky Wang public void testViewNoFragmentBindingsWithFragment_thirdConstructor() throws Exception { 422*f585d8a3SJacky Wang TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); 423*f585d8a3SJacky Wang TestView view = new TestView(fragment.getContext(), /* attrs= */ null, /* defStyleAttr= */ 0); 424*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 425*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 426*f585d8a3SJacky Wang } 427*f585d8a3SJacky Wang 428*f585d8a3SJacky Wang @Test 429*f585d8a3SJacky Wang @Config(sdk = 21) testViewNoFragmentBindingsWithFragment_fourthConstructor_presentOnTwentyOne()430*f585d8a3SJacky Wang public void testViewNoFragmentBindingsWithFragment_fourthConstructor_presentOnTwentyOne() 431*f585d8a3SJacky Wang throws Exception { 432*f585d8a3SJacky Wang TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); 433*f585d8a3SJacky Wang TestView view = 434*f585d8a3SJacky Wang new TestView( 435*f585d8a3SJacky Wang fragment.getContext(), /* attrs= */ null, /* defStyleAttr= */ 0, /* defStyleRes= */ 0); 436*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 437*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 438*f585d8a3SJacky Wang } 439*f585d8a3SJacky Wang 440*f585d8a3SJacky Wang @Test testServiceInjection()441*f585d8a3SJacky Wang public void testServiceInjection() throws Exception { 442*f585d8a3SJacky Wang TestService testService = Robolectric.setupService(TestService.class); 443*f585d8a3SJacky Wang assertThat(testService.appBinding).isEqualTo(APP_BINDING); 444*f585d8a3SJacky Wang assertThat(testService.serviceBinding).isEqualTo(SERVICE_BINDING); 445*f585d8a3SJacky Wang } 446*f585d8a3SJacky Wang 447*f585d8a3SJacky Wang @Test testIntentServiceInjection()448*f585d8a3SJacky Wang public void testIntentServiceInjection() throws Exception { 449*f585d8a3SJacky Wang TestIntentService testIntentService = Robolectric.setupService(TestIntentService.class); 450*f585d8a3SJacky Wang assertThat(testIntentService.appBinding).isEqualTo(APP_BINDING); 451*f585d8a3SJacky Wang assertThat(testIntentService.serviceBinding).isEqualTo(SERVICE_BINDING); 452*f585d8a3SJacky Wang } 453*f585d8a3SJacky Wang 454*f585d8a3SJacky Wang @Test testBroadcastReceiverInjection()455*f585d8a3SJacky Wang public void testBroadcastReceiverInjection() throws Exception { 456*f585d8a3SJacky Wang TestBroadcastReceiver testBroadcastReceiver = new TestBroadcastReceiver(); 457*f585d8a3SJacky Wang Intent intent = new Intent(); 458*f585d8a3SJacky Wang testBroadcastReceiver.onReceive(getApplicationContext(), intent); 459*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.appBinding).isEqualTo(APP_BINDING); 460*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.lastIntent).isSameInstanceAs(intent); 461*f585d8a3SJacky Wang } 462*f585d8a3SJacky Wang 463*f585d8a3SJacky Wang @Test testBroadcastReceiverWithBaseImplementingOnReceiveInjection()464*f585d8a3SJacky Wang public void testBroadcastReceiverWithBaseImplementingOnReceiveInjection() throws Exception { 465*f585d8a3SJacky Wang TestBroadcastReceiverWithBaseImplementingOnReceive testBroadcastReceiver = 466*f585d8a3SJacky Wang new TestBroadcastReceiverWithBaseImplementingOnReceive(); 467*f585d8a3SJacky Wang Intent intent = new Intent(); 468*f585d8a3SJacky Wang testBroadcastReceiver.onReceive(getApplicationContext(), intent); 469*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.appBinding).isEqualTo(APP_BINDING); 470*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.lastIntent).isSameInstanceAs(intent); 471*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.baseLastIntent).isSameInstanceAs(intent); 472*f585d8a3SJacky Wang } 473*f585d8a3SJacky Wang 474*f585d8a3SJacky Wang @Test testViewWithFragmentBindingsWithFragment()475*f585d8a3SJacky Wang public void testViewWithFragmentBindingsWithFragment() throws Exception { 476*f585d8a3SJacky Wang TestFragment fragment = setupFragment(TestActivity.class, new TestFragment()); 477*f585d8a3SJacky Wang 478*f585d8a3SJacky Wang Context fragmentContext = fragment.getContext(); 479*f585d8a3SJacky Wang TestViewWithFragmentBindings view = new TestViewWithFragmentBindings(fragmentContext); 480*f585d8a3SJacky Wang assertThat(view.appBinding).isEqualTo(APP_BINDING); 481*f585d8a3SJacky Wang assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING); 482*f585d8a3SJacky Wang assertThat(view.fragmentBinding).isEqualTo(FRAGMENT_BINDING); 483*f585d8a3SJacky Wang } 484*f585d8a3SJacky Wang 485*f585d8a3SJacky Wang @Test testViewWithFragmentBindingsFailsWithActivity()486*f585d8a3SJacky Wang public void testViewWithFragmentBindingsFailsWithActivity() throws Exception { 487*f585d8a3SJacky Wang TestActivity activity = Robolectric.setupActivity(TestActivity.class); 488*f585d8a3SJacky Wang try { 489*f585d8a3SJacky Wang new TestViewWithFragmentBindings(activity); 490*f585d8a3SJacky Wang fail("Expected test to fail but it passes!"); 491*f585d8a3SJacky Wang } catch (IllegalStateException e) { 492*f585d8a3SJacky Wang assertThat(e) 493*f585d8a3SJacky Wang .hasMessageThat() 494*f585d8a3SJacky Wang .contains( 495*f585d8a3SJacky Wang "@WithFragmentBindings Hilt view must be attached to an @AndroidEntryPoint Fragment"); 496*f585d8a3SJacky Wang } 497*f585d8a3SJacky Wang } 498*f585d8a3SJacky Wang 499*f585d8a3SJacky Wang @Test testFragmentAttachedToNonHiltActivityFails()500*f585d8a3SJacky Wang public void testFragmentAttachedToNonHiltActivityFails() throws Exception { 501*f585d8a3SJacky Wang NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class); 502*f585d8a3SJacky Wang try { 503*f585d8a3SJacky Wang activity 504*f585d8a3SJacky Wang .getSupportFragmentManager() 505*f585d8a3SJacky Wang .beginTransaction() 506*f585d8a3SJacky Wang .add(new TestFragment(), null) 507*f585d8a3SJacky Wang .commitNow(); 508*f585d8a3SJacky Wang fail("Expected test to fail but it passes!"); 509*f585d8a3SJacky Wang } catch (IllegalStateException e) { 510*f585d8a3SJacky Wang assertThat(e) 511*f585d8a3SJacky Wang .hasMessageThat() 512*f585d8a3SJacky Wang .contains("Hilt Fragments must be attached to an @AndroidEntryPoint Activity"); 513*f585d8a3SJacky Wang } 514*f585d8a3SJacky Wang } 515*f585d8a3SJacky Wang 516*f585d8a3SJacky Wang @Test testViewAttachedToNonHiltActivityFails()517*f585d8a3SJacky Wang public void testViewAttachedToNonHiltActivityFails() throws Exception { 518*f585d8a3SJacky Wang NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class); 519*f585d8a3SJacky Wang try { 520*f585d8a3SJacky Wang new TestView(activity); 521*f585d8a3SJacky Wang fail("Expected test to fail but it passes!"); 522*f585d8a3SJacky Wang } catch (IllegalStateException e) { 523*f585d8a3SJacky Wang assertThat(e) 524*f585d8a3SJacky Wang .hasMessageThat() 525*f585d8a3SJacky Wang .contains("Hilt view must be attached to an @AndroidEntryPoint Fragment or Activity"); 526*f585d8a3SJacky Wang } 527*f585d8a3SJacky Wang } 528*f585d8a3SJacky Wang 529*f585d8a3SJacky Wang @Test testViewAttachedToNonHiltFragmentFails()530*f585d8a3SJacky Wang public void testViewAttachedToNonHiltFragmentFails() throws Exception { 531*f585d8a3SJacky Wang NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class); 532*f585d8a3SJacky Wang NonHiltFragment fragment = new NonHiltFragment(); 533*f585d8a3SJacky Wang activity.getSupportFragmentManager().beginTransaction().add(fragment, null).commitNow(); 534*f585d8a3SJacky Wang Context nonHiltContext = fragment.getContext(); 535*f585d8a3SJacky Wang try { 536*f585d8a3SJacky Wang new TestView(nonHiltContext); 537*f585d8a3SJacky Wang fail("Expected test to fail but it passes!"); 538*f585d8a3SJacky Wang } catch (IllegalStateException e) { 539*f585d8a3SJacky Wang assertThat(e) 540*f585d8a3SJacky Wang .hasMessageThat() 541*f585d8a3SJacky Wang .contains("Hilt view must be attached to an @AndroidEntryPoint Fragment or Activity"); 542*f585d8a3SJacky Wang } 543*f585d8a3SJacky Wang } 544*f585d8a3SJacky Wang 545*f585d8a3SJacky Wang @Test testViewAttachedToApplicationContextFails()546*f585d8a3SJacky Wang public void testViewAttachedToApplicationContextFails() throws Exception { 547*f585d8a3SJacky Wang try { 548*f585d8a3SJacky Wang new TestView(getApplicationContext()); 549*f585d8a3SJacky Wang fail("Expected test to fail but it passes!"); 550*f585d8a3SJacky Wang } catch (IllegalStateException e) { 551*f585d8a3SJacky Wang assertThat(e) 552*f585d8a3SJacky Wang .hasMessageThat() 553*f585d8a3SJacky Wang .contains( 554*f585d8a3SJacky Wang "Hilt view cannot be created using the application context. " 555*f585d8a3SJacky Wang + "Use a Hilt Fragment or Activity context"); 556*f585d8a3SJacky Wang } 557*f585d8a3SJacky Wang } 558*f585d8a3SJacky Wang 559*f585d8a3SJacky Wang /** Hilt Activity that manually calls inject(). */ 560*f585d8a3SJacky Wang @AndroidEntryPoint(FragmentActivity.class) 561*f585d8a3SJacky Wang public static final class DoubleInjectActivity extends Hilt_InjectionTest_DoubleInjectActivity { 562*f585d8a3SJacky Wang @Inject Long counter; 563*f585d8a3SJacky Wang 564*f585d8a3SJacky Wang @Override onCreate(Bundle onSavedInstanceState)565*f585d8a3SJacky Wang public void onCreate(Bundle onSavedInstanceState) { 566*f585d8a3SJacky Wang inject(); 567*f585d8a3SJacky Wang super.onCreate(onSavedInstanceState); 568*f585d8a3SJacky Wang } 569*f585d8a3SJacky Wang } 570*f585d8a3SJacky Wang 571*f585d8a3SJacky Wang @Test testActivityDoesNotInjectTwice()572*f585d8a3SJacky Wang public void testActivityDoesNotInjectTwice() throws Exception { 573*f585d8a3SJacky Wang ActivityController<DoubleInjectActivity> controller = 574*f585d8a3SJacky Wang Robolectric.buildActivity(DoubleInjectActivity.class); 575*f585d8a3SJacky Wang controller.create(); 576*f585d8a3SJacky Wang assertThat(controller.get().counter).isEqualTo(1L); 577*f585d8a3SJacky Wang } 578*f585d8a3SJacky Wang 579*f585d8a3SJacky Wang /** Hilt Fragment that manually calls inject(). */ 580*f585d8a3SJacky Wang @AndroidEntryPoint(Fragment.class) 581*f585d8a3SJacky Wang public static final class DoubleInjectFragment extends Hilt_InjectionTest_DoubleInjectFragment { 582*f585d8a3SJacky Wang @Inject Long counter; 583*f585d8a3SJacky Wang 584*f585d8a3SJacky Wang @Override onAttach(Context context)585*f585d8a3SJacky Wang public void onAttach(Context context) { 586*f585d8a3SJacky Wang inject(); 587*f585d8a3SJacky Wang super.onAttach(context); 588*f585d8a3SJacky Wang } 589*f585d8a3SJacky Wang 590*f585d8a3SJacky Wang @Override onAttach(Activity activity)591*f585d8a3SJacky Wang public void onAttach(Activity activity) { 592*f585d8a3SJacky Wang inject(); 593*f585d8a3SJacky Wang super.onAttach(activity); 594*f585d8a3SJacky Wang } 595*f585d8a3SJacky Wang } 596*f585d8a3SJacky Wang 597*f585d8a3SJacky Wang @Test testFragmentDoesNotInjectTwice()598*f585d8a3SJacky Wang public void testFragmentDoesNotInjectTwice() throws Exception { 599*f585d8a3SJacky Wang DoubleInjectFragment fragment = setupFragment(TestActivity.class, new DoubleInjectFragment()); 600*f585d8a3SJacky Wang assertThat(fragment.counter).isEqualTo(1L); 601*f585d8a3SJacky Wang } 602*f585d8a3SJacky Wang 603*f585d8a3SJacky Wang /** Hilt View that manually calls inject(). */ 604*f585d8a3SJacky Wang @AndroidEntryPoint(LinearLayout.class) 605*f585d8a3SJacky Wang public static final class DoubleInjectView extends Hilt_InjectionTest_DoubleInjectView { 606*f585d8a3SJacky Wang @Inject Long counter; 607*f585d8a3SJacky Wang DoubleInjectView(Context context)608*f585d8a3SJacky Wang DoubleInjectView(Context context) { 609*f585d8a3SJacky Wang super(context); 610*f585d8a3SJacky Wang inject(); 611*f585d8a3SJacky Wang } 612*f585d8a3SJacky Wang DoubleInjectView(Context context, AttributeSet attrs)613*f585d8a3SJacky Wang DoubleInjectView(Context context, AttributeSet attrs) { 614*f585d8a3SJacky Wang super(context, attrs); 615*f585d8a3SJacky Wang inject(); 616*f585d8a3SJacky Wang } 617*f585d8a3SJacky Wang DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr)618*f585d8a3SJacky Wang DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr) { 619*f585d8a3SJacky Wang super(context, attrs, defStyleAttr); 620*f585d8a3SJacky Wang inject(); 621*f585d8a3SJacky Wang } 622*f585d8a3SJacky Wang 623*f585d8a3SJacky Wang @TargetApi(21) DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)624*f585d8a3SJacky Wang DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 625*f585d8a3SJacky Wang super(context, attrs, defStyleAttr, defStyleRes); 626*f585d8a3SJacky Wang inject(); 627*f585d8a3SJacky Wang } 628*f585d8a3SJacky Wang } 629*f585d8a3SJacky Wang 630*f585d8a3SJacky Wang @Test testViewDoesNotInjectTwice()631*f585d8a3SJacky Wang public void testViewDoesNotInjectTwice() throws Exception { 632*f585d8a3SJacky Wang TestActivity activity = Robolectric.setupActivity(TestActivity.class); 633*f585d8a3SJacky Wang DoubleInjectView view = new DoubleInjectView(activity); 634*f585d8a3SJacky Wang assertThat(view.counter).isEqualTo(1L); 635*f585d8a3SJacky Wang } 636*f585d8a3SJacky Wang 637*f585d8a3SJacky Wang /** Hilt Service that manually calls inject(). */ 638*f585d8a3SJacky Wang @AndroidEntryPoint(Service.class) 639*f585d8a3SJacky Wang public static final class DoubleInjectService extends Hilt_InjectionTest_DoubleInjectService { 640*f585d8a3SJacky Wang @Inject Long counter; 641*f585d8a3SJacky Wang onCreate()642*f585d8a3SJacky Wang @Override public void onCreate() { 643*f585d8a3SJacky Wang inject(); 644*f585d8a3SJacky Wang super.onCreate(); 645*f585d8a3SJacky Wang } 646*f585d8a3SJacky Wang 647*f585d8a3SJacky Wang @Override onBind(Intent intent)648*f585d8a3SJacky Wang public IBinder onBind(Intent intent) { 649*f585d8a3SJacky Wang return null; 650*f585d8a3SJacky Wang } 651*f585d8a3SJacky Wang } 652*f585d8a3SJacky Wang 653*f585d8a3SJacky Wang @Test testServiceDoesNotInjectTwice()654*f585d8a3SJacky Wang public void testServiceDoesNotInjectTwice() throws Exception { 655*f585d8a3SJacky Wang DoubleInjectService testService = Robolectric.setupService(DoubleInjectService.class); 656*f585d8a3SJacky Wang assertThat(testService.counter).isEqualTo(1L); 657*f585d8a3SJacky Wang } 658*f585d8a3SJacky Wang 659*f585d8a3SJacky Wang /** Hilt BroadcastReceiver that manually calls inject(). */ 660*f585d8a3SJacky Wang @AndroidEntryPoint(BroadcastReceiver.class) 661*f585d8a3SJacky Wang public static final class DoubleInjectBroadcastReceiver 662*f585d8a3SJacky Wang extends Hilt_InjectionTest_DoubleInjectBroadcastReceiver { 663*f585d8a3SJacky Wang @Inject Long counter; 664*f585d8a3SJacky Wang 665*f585d8a3SJacky Wang @Override onReceive(Context context, Intent intent)666*f585d8a3SJacky Wang public void onReceive(Context context, Intent intent) { 667*f585d8a3SJacky Wang inject(context); 668*f585d8a3SJacky Wang super.onReceive(context, intent); 669*f585d8a3SJacky Wang } 670*f585d8a3SJacky Wang } 671*f585d8a3SJacky Wang 672*f585d8a3SJacky Wang @Test testBroadcastReceiverDoesNotInjectTwice()673*f585d8a3SJacky Wang public void testBroadcastReceiverDoesNotInjectTwice() throws Exception { 674*f585d8a3SJacky Wang DoubleInjectBroadcastReceiver testBroadcastReceiver = new DoubleInjectBroadcastReceiver(); 675*f585d8a3SJacky Wang Intent intent = new Intent(); 676*f585d8a3SJacky Wang testBroadcastReceiver.onReceive(getApplicationContext(), intent); 677*f585d8a3SJacky Wang assertThat(testBroadcastReceiver.counter).isEqualTo(1L); 678*f585d8a3SJacky Wang } 679*f585d8a3SJacky Wang setupFragment( Class<? extends FragmentActivity> activityClass, T fragment)680*f585d8a3SJacky Wang private static <T extends Fragment> T setupFragment( 681*f585d8a3SJacky Wang Class<? extends FragmentActivity> activityClass, T fragment) { 682*f585d8a3SJacky Wang FragmentActivity activity = Robolectric.setupActivity(activityClass); 683*f585d8a3SJacky Wang attachFragment(activity, fragment); 684*f585d8a3SJacky Wang return fragment; 685*f585d8a3SJacky Wang } 686*f585d8a3SJacky Wang attachFragment(FragmentActivity activity, Fragment fragment)687*f585d8a3SJacky Wang private static void attachFragment(FragmentActivity activity, Fragment fragment) { 688*f585d8a3SJacky Wang activity.getSupportFragmentManager().beginTransaction().add(fragment, "").commitNow(); 689*f585d8a3SJacky Wang } 690*f585d8a3SJacky Wang } 691