组件架构ViewModel

组件架构ViewModel

  • 1.What?
  • 2.使用方法
    • 1.创建需要保存的ViewModel
    • 2.创建Provider ,通过provider,获取保存在ViewModelStore 中的 ViewModel 实例
  • 3.ViewModel
    • 1. 关联application的ViewModel
  • 4.ViewModelProvider
    • 构造函数
      • Factory
    • 获取ViewModel 实例
  • 5.ViewModelStore
  • 6.Activity 和fragment 的组件架构
  • 7总结

1.What?

1.可以用来管理和准备数据的类,通常用于fragment 和activity(实现了ViewModelStoreOwner,默认提供了ViewModelStore)。
2.作为 信息通讯的桥梁(包括,activity,fragment 和应用其它组件)。
3.ViewModel 的生命周期 仅在 ViewModelStore 销毁时,才会销毁。

以上仅是对官方文旦的个人总结。

2.使用方法

1.创建需要保存的ViewModel

public class BoyiKiaViewModel extends ViewModel {

}

2.创建Provider ,通过provider,获取保存在ViewModelStore 中的 ViewModel 实例


     ViewModelProvider provider=new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory());
     
        BoyiKiaViewModel boyiKiaViewModel = provider.get(BoyiKiaViewModel.class);

3.ViewModel

当viewModel 销毁时,会执行 onCleared 方法

public abstract class ViewModel {
    /**
     * This method will be called when this ViewModel is no longer used and will be destroyed.
     * 

* It is useful when ViewModel observes some data and you need to clear this subscription to * prevent a leak of this ViewModel. */ @SuppressWarnings("WeakerAccess") protected void onCleared() { } }

1. 关联application的ViewModel

public class AndroidViewModel extends ViewModel {
    @SuppressLint("StaticFieldLeak")
    private Application mApplication;

    public AndroidViewModel(@NonNull Application application) {
        mApplication = application;
    }

    /**
     * Return the application.
     */
    @SuppressWarnings("TypeParameterUnusedInFormals")
    @NonNull
    public <T extends Application> T getApplication() {
        //noinspection unchecked
        return (T) mApplication;
    }
}

4.ViewModelProvider

构造函数

绑定ViewModel 的构造器 和 ViewStore

//1.
 public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
        mFactory = factory;
        this.mViewModelStore = store;
    }

//2. 通过ViewModelStoreOwner 获取 ViewStore(acvitivity 创建时 默认实现了一个ModelStoreOwner)

public interface ViewModelStoreOwner {
    /**
     * Returns owned {@link ViewModelStore}
     *
     * @return a {@code ViewModelStore}
     */
    @NonNull
    ViewModelStore getViewModelStore();
}
 public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
        this(owner.getViewModelStore(), factory);
    }

Factory

ViewModel 实例构造器

 public interface Factory {
        /**
         * Creates a new instance of the given {@code Class}.
         * 

* * @param modelClass a {@code Class} whose instance is requested * @param The type parameter for the ViewModel. * @return a newly created ViewModel */ @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass); }

默认实现的构造器

public static class NewInstanceFactory implements Factory {

        @SuppressWarnings("ClassNewInstance")
        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            //noinspection TryWithIdenticalCatches
            try {
                return modelClass.newInstance();
            } catch (InstantiationException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            }
        }
    }


 /**
     * {@link Factory} which may create {@link AndroidViewModel} and
     * {@link ViewModel}, which have an empty constructor.
     */
    public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

        private static AndroidViewModelFactory sInstance;

        /**
         * Retrieve a singleton instance of AndroidViewModelFactory.
         *
         * @param application an application to pass in {@link AndroidViewModel}
         * @return A valid {@link AndroidViewModelFactory}
         */
        @NonNull
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }
            return sInstance;
        }

        private Application mApplication;

        /**
         * Creates a {@code AndroidViewModelFactory}
         *
         * @param application an application to pass in {@link AndroidViewModel}
         */
        public AndroidViewModelFactory(@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);
        }
    }

获取ViewModel 实例

从viewModelStore 中获取ViewModel ,没有的话则实例一个viewModel ,放入viewModelStore中

//ViewModelProvider.java

    private static final String DEFAULT_KEY =
            "androidx.lifecycle.ViewModelProvider.DefaultKey";
     @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
        String canonicalName = modelClass.getCanonicalName();
        if (canonicalName == null) {
            throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
        }
        return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
    }



  @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = mViewModelStore.get(key);

        if (modelClass.isInstance(viewModel)) {
            //noinspection unchecked
            return (T) viewModel;
        } else {
            //noinspection StatementWithEmptyBody
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }

        viewModel = mFactory.create(modelClass);
        mViewModelStore.put(key, viewModel);
        //noinspection unchecked
        return (T) viewModel;
    }

5.ViewModelStore

默认维持了一个散列表

public class ViewModelStore {

    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }

    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
     //销毁所有存储的ViewModel
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.onCleared();
        }
        mMap.clear();
    }
}

6.Activity 和fragment 的组件架构

activity 中默认维持着一个 ViewModelStore

//FragmentActivity.java

   @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        if (getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the "
                    + "Application instance. You can't request ViewModel before onCreate call.");
        }
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }


 //销毁viewModelStore
  @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mViewModelStore != null && !isChangingConfigurations()) {
            mViewModelStore.clear();
        }

        mFragments.dispatchDestroy();
    }

fragment 默认持有的ViewModelStore

//fragment.java
   @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        if (getContext() == null) {
            throw new IllegalStateException("Can't access ViewModels from detached fragment");
        }
        if (mViewModelStore == null) {
            mViewModelStore = new ViewModelStore();
        }
        return mViewModelStore;
    }
 
 //销毁viewModelStore
 @CallSuper
    public void onDestroy() {
 
        if (mViewModelStore != null && !isChangingConfigurations) {
            mViewModelStore.clear();
        }
    }

7总结

  1. 不同组件,只要持有同一个ViewModelStore ,就可以通过获取 ViewModel 实现数据共享
  2. activity 和fragment ,或者同一个宿主下的fragment实现数组 共享,可以使用宿主的 viewModelStore.
  3. activity 和 fragment 中的viewModelStore 只有在组件销毁的时候,才进行销毁。

你可能感兴趣的:(Android)