Java tutorial
/* * Copyright (C) 2017 The Android Open Source Project * * 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 android.arch.lifecycle; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Application; import android.arch.lifecycle.ViewModelProvider.Factory; import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import java.lang.reflect.InvocationTargetException; /** * Utilities methods for {@link ViewModelStore} class. */ public class ViewModelProviders { @SuppressLint("StaticFieldLeak") private static DefaultFactory sDefaultFactory; private static void initializeFactoryIfNeeded(Application application) { if (sDefaultFactory == null) { sDefaultFactory = new DefaultFactory(application); } } private static Application checkApplication(Activity activity) { Application application = activity.getApplication(); if (application == null) { throw new IllegalStateException("Your activity/fragment is not yet attached to " + "Application. You can't request ViewModel before onCreate call."); } return application; } private static Activity checkActivity(Fragment fragment) { Activity activity = fragment.getActivity(); if (activity == null) { throw new IllegalStateException("Can't create ViewModelProvider for detached fragment"); } return activity; } /** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given * {@code fragment} is alive. More detailed explanation is in {@link ViewModel}. * <p> * It uses {@link DefaultFactory} to instantiate new ViewModels. * * @param fragment a fragment, in whose scope ViewModels should be retained * @return a ViewModelProvider instance */ @MainThread public static ViewModelProvider of(@NonNull Fragment fragment) { initializeFactoryIfNeeded(checkApplication(checkActivity(fragment))); return new ViewModelProvider(ViewModelStores.of(fragment), sDefaultFactory); } /** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity * is alive. More detailed explanation is in {@link ViewModel}. * <p> * It uses {@link DefaultFactory} to instantiate new ViewModels. * * @param activity an activity, in whose scope ViewModels should be retained * @return a ViewModelProvider instance */ @MainThread public static ViewModelProvider of(@NonNull FragmentActivity activity) { initializeFactoryIfNeeded(checkApplication(activity)); return new ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory); } /** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given * {@code fragment} is alive. More detailed explanation is in {@link ViewModel}. * <p> * It uses the given {@link Factory} to instantiate new ViewModels. * * @param fragment a fragment, in whose scope ViewModels should be retained * @param factory a {@code Factory} to instantiate new ViewModels * @return a ViewModelProvider instance */ @MainThread public static ViewModelProvider of(@NonNull Fragment fragment, @NonNull Factory factory) { checkApplication(checkActivity(fragment)); return new ViewModelProvider(ViewModelStores.of(fragment), factory); } /** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity * is alive. More detailed explanation is in {@link ViewModel}. * <p> * It uses the given {@link Factory} to instantiate new ViewModels. * * @param activity an activity, in whose scope ViewModels should be retained * @param factory a {@code Factory} to instantiate new ViewModels * @return a ViewModelProvider instance */ @MainThread public static ViewModelProvider of(@NonNull FragmentActivity activity, @NonNull Factory factory) { checkApplication(activity); return new ViewModelProvider(ViewModelStores.of(activity), factory); } /** * {@link Factory} which may create {@link AndroidViewModel} and * {@link ViewModel}, which have an empty constructor. */ @SuppressWarnings("WeakerAccess") public static class DefaultFactory extends ViewModelProvider.NewInstanceFactory { private Application mApplication; /** * Creates a {@code DefaultFactory} * * @param application an application to pass in {@link AndroidViewModel} */ public DefaultFactory(@NonNull Application application) { mApplication = application; } @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { if (AndroidViewModel.class.isAssignableFrom(modelClass)) { //noinspection TryWithIdenticalCatches try { return modelClass.getConstructor(Application.class).newInstance(mApplication); } catch (NoSuchMethodException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (IllegalAccessException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InstantiationException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InvocationTargetException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } } return super.create(modelClass); } } }