diff options
Diffstat (limited to 'java/dagger/hilt/android/internal/lifecycle')
5 files changed, 103 insertions, 42 deletions
diff --git a/java/dagger/hilt/android/internal/lifecycle/BUILD b/java/dagger/hilt/android/internal/lifecycle/BUILD index 17812c904..b3ecfc22e 100644 --- a/java/dagger/hilt/android/internal/lifecycle/BUILD +++ b/java/dagger/hilt/android/internal/lifecycle/BUILD @@ -25,12 +25,12 @@ android_library( "//java/dagger/hilt:entry_point", "//java/dagger/hilt:install_in", "//java/dagger/hilt/android/components", + "//java/dagger/hilt/android/components:view_model_component", "//java/dagger/hilt/android/internal/builders", "//java/dagger/hilt/android/qualifiers", "@maven//:androidx_activity_activity", "@maven//:androidx_annotation_annotation", "@maven//:androidx_fragment_fragment", - "@maven//:androidx_lifecycle_lifecycle_common", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", "@maven//:androidx_savedstate_savedstate", diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java new file mode 100644 index 000000000..becce8cdb --- /dev/null +++ b/java/dagger/hilt/android/internal/lifecycle/DefaultActivityViewModelFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 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.hilt.android.internal.lifecycle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** Qualifier for the default view model factory used by @AndroidEntryPoint annotated activities. */ +@Qualifier +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) +public @interface DefaultActivityViewModelFactory {} diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java new file mode 100644 index 000000000..996705376 --- /dev/null +++ b/java/dagger/hilt/android/internal/lifecycle/DefaultFragmentViewModelFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 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.hilt.android.internal.lifecycle; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** Qualifier for the default view model factory used by @AndroidEntryPoint annotated fragments. */ +@Qualifier +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) +public @interface DefaultFragmentViewModelFactory {} diff --git a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java index 448847cd3..427822dbb 100644 --- a/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java +++ b/java/dagger/hilt/android/internal/lifecycle/DefaultViewModelFactories.java @@ -50,11 +50,10 @@ public final class DefaultViewModelFactories { * * <p>Do not use except in Hilt generated code! */ - public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity, - ViewModelProvider.Factory delegateFactory) { + public static ViewModelProvider.Factory getActivityFactory(ComponentActivity activity) { return EntryPoints.get(activity, ActivityEntryPoint.class) .getHiltInternalFactoryFactory() - .fromActivity(activity, delegateFactory); + .fromActivity(activity); } /** @@ -62,11 +61,10 @@ public final class DefaultViewModelFactories { * * <p>Do not use except in Hilt generated code! */ - public static ViewModelProvider.Factory getFragmentFactory( - Fragment fragment, ViewModelProvider.Factory delegateFactory) { + public static ViewModelProvider.Factory getFragmentFactory(Fragment fragment) { return EntryPoints.get(fragment, FragmentEntryPoint.class) .getHiltInternalFactoryFactory() - .fromFragment(fragment, delegateFactory); + .fromFragment(fragment); } /** Internal factory for the Hilt ViewModel Factory. */ @@ -75,28 +73,33 @@ public final class DefaultViewModelFactories { private final Application application; private final Set<String> keySet; private final ViewModelComponentBuilder viewModelComponentBuilder; + @Nullable private final ViewModelProvider.Factory defaultActivityFactory; + @Nullable private final ViewModelProvider.Factory defaultFragmentFactory; @Inject InternalFactoryFactory( Application application, @HiltViewModelMap.KeySet Set<String> keySet, - ViewModelComponentBuilder viewModelComponentBuilder) { + ViewModelComponentBuilder viewModelComponentBuilder, + // These default factory bindings are temporary for the transition of deprecating + // the Hilt ViewModel extension for the built-in support + @DefaultActivityViewModelFactory Set<ViewModelProvider.Factory> defaultActivityFactorySet, + @DefaultFragmentViewModelFactory Set<ViewModelProvider.Factory> defaultFragmentFactorySet) { this.application = application; this.keySet = keySet; this.viewModelComponentBuilder = viewModelComponentBuilder; + this.defaultActivityFactory = getFactoryFromSet(defaultActivityFactorySet); + this.defaultFragmentFactory = getFactoryFromSet(defaultFragmentFactorySet); } - ViewModelProvider.Factory fromActivity( - ComponentActivity activity, ViewModelProvider.Factory delegateFactory) { - return getHiltViewModelFactory( - activity, + ViewModelProvider.Factory fromActivity(ComponentActivity activity) { + return getHiltViewModelFactory(activity, activity.getIntent() != null ? activity.getIntent().getExtras() : null, - delegateFactory); + defaultActivityFactory); } - ViewModelProvider.Factory fromFragment( - Fragment fragment, ViewModelProvider.Factory delegateFactory) { - return getHiltViewModelFactory(fragment, fragment.getArguments(), delegateFactory); + ViewModelProvider.Factory fromFragment(Fragment fragment) { + return getHiltViewModelFactory(fragment, fragment.getArguments(), defaultFragmentFactory); } private ViewModelProvider.Factory getHiltViewModelFactory( @@ -109,6 +112,24 @@ public final class DefaultViewModelFactories { return new HiltViewModelFactory( owner, defaultArgs, keySet, delegate, viewModelComponentBuilder); } + + @Nullable + private static ViewModelProvider.Factory getFactoryFromSet(Set<ViewModelProvider.Factory> set) { + // A multibinding set is used instead of BindsOptionalOf because Optional is not available in + // Android until API 24 and we don't want to have Guava as a transitive dependency. + if (set.isEmpty()) { + return null; + } + if (set.size() > 1) { + throw new IllegalStateException( + "At most one default view model factory is expected. Found " + set); + } + ViewModelProvider.Factory factory = set.iterator().next(); + if (factory == null) { + throw new IllegalStateException("Default view model factory must not be null."); + } + return factory; + } } /** The activity module to declare the optional factories. */ @@ -118,6 +139,14 @@ public final class DefaultViewModelFactories { @Multibinds @HiltViewModelMap.KeySet abstract Set<String> viewModelKeys(); + + @Multibinds + @DefaultActivityViewModelFactory + Set<ViewModelProvider.Factory> defaultActivityViewModelFactory(); + + @Multibinds + @DefaultFragmentViewModelFactory + Set<ViewModelProvider.Factory> defaultFragmentViewModelFactory(); } /** The activity entry point to retrieve the factory. */ diff --git a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java index 443894127..3b0d3bc43 100644 --- a/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java +++ b/java/dagger/hilt/android/internal/lifecycle/HiltViewModelFactory.java @@ -16,7 +16,6 @@ package dagger.hilt.android.internal.lifecycle; -import android.app.Activity; import androidx.lifecycle.AbstractSavedStateViewModelFactory; import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel; @@ -29,7 +28,6 @@ import dagger.Module; import dagger.hilt.EntryPoint; import dagger.hilt.EntryPoints; import dagger.hilt.InstallIn; -import dagger.hilt.android.components.ActivityComponent; import dagger.hilt.android.components.ViewModelComponent; import dagger.hilt.android.internal.builders.ViewModelComponentBuilder; import dagger.multibindings.Multibinds; @@ -111,28 +109,4 @@ public final class HiltViewModelFactory implements ViewModelProvider.Factory { return delegateFactory.create(modelClass); } } - - @EntryPoint - @InstallIn(ActivityComponent.class) - interface ActivityCreatorEntryPoint { - @HiltViewModelMap.KeySet - Set<String> getViewModelKeys(); - ViewModelComponentBuilder getViewModelComponentBuilder(); - } - - public static ViewModelProvider.Factory createInternal( - @NonNull Activity activity, - @NonNull SavedStateRegistryOwner owner, - @Nullable Bundle defaultArgs, - @NonNull ViewModelProvider.Factory delegateFactory) { - ActivityCreatorEntryPoint entryPoint = - EntryPoints.get(activity, ActivityCreatorEntryPoint.class); - return new HiltViewModelFactory( - owner, - defaultArgs, - entryPoint.getViewModelKeys(), - delegateFactory, - entryPoint.getViewModelComponentBuilder() - ); - } } |