jetpack之ViewModel的源码解读

源码版本:Android 10

一、ViewModel基本使用方法

package com.study.viewmodeldemo

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

/**
 * 旋转的model
 */
class RotationModel : ViewModel() {
    var count = 0
    val currentLiveData: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }
}
package com.study.viewmodeldemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    lateinit var rotationModel: RotationModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val androidViewModelFactory =
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        //此处不要用androidViewModelFactory.create(RotationModel::class.java) 直接创建对象,否则每次
        //创建出来的对象都是不一样的,那么就失去了ViewModel保存数据的优势
        rotationModel = ViewModelProvider(
            viewModelStore,
            androidViewModelFactory
        ).get(RotationModel::class.java)
        //每次屏幕旋转所产生的rotationModel都是同一实例
        Log.e("jetpack", rotationModel.toString())
        rotationModel.currentLiveData.observe(this, Observer<String> {
            tv.text = it
        })

        bt.setOnClickListener {
            rotationModel.count++
            rotationModel.currentLiveData.value = "jetpack${rotationModel.count}"
        }
    }
}

二、ViewModel源码分析

2.1 ViewModelProvider 源码分析

package androidx.lifecycle;

import android.app.Application;

import androidx.annotation.MainThread;
import androidx.annotation.NonNull;

import java.lang.reflect.InvocationTargetException;


@SuppressWarnings("WeakerAccess")
public class ViewModelProvider {

    private static final String DEFAULT_KEY =
            "androidx.lifecycle.ViewModelProvider.DefaultKey";

    
    public interface Factory {
        @NonNull
        <T extends ViewModel> T create(@NonNull Class<T> modelClass);
    }

    
    abstract static class KeyedFactory implements Factory {
       
        @NonNull
        public abstract <T extends ViewModel> T create(@NonNull String key,
                @NonNull Class<T> modelClass);

        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            throw new UnsupportedOperationException("create(String, Class) must be called on "
                    + "implementaions of KeyedFactory");
        }
    }

    private final Factory mFactory;
    private final ViewModelStore mViewModelStore;

   
    public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
        this(owner.getViewModelStore(), factory);
    }

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

  
    @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);
    }

    
    //根据传入的class对象获取对应的ViewModel
    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = mViewModelStore.get(key);
        //viewModel是当前modelClass所对应的实例 
        if (modelClass.isInstance(viewModel)) {
        //直接返回
            return (T) viewModel;
        } else {
            if (viewModel != null) {
                
            }
        }
        if (mFactory instanceof KeyedFactory) {
            viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
        } else {
            viewModel = (mFactory).create(modelClass);
        }
        //创建出实例将其保存
        mViewModelStore.put(key, viewModel);
        return (T) viewModel;
    }

   
    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);
            }
        }
    }

  //适用于需要Android上下文的ViewModel
  public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

        private static AndroidViewModelFactory sInstance;

       
        @NonNull
        public static AndroidViewModelFactory getInstance(@NonNull Application application) {
            if (sInstance == null) {
                sInstance = new AndroidViewModelFactory(application);
            }
            return sInstance;
        }

        private Application mApplication;

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

        //根据给定的class对象创建对应的实例
        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        //继承至AndroidViewModel则走if分支,否则调用父类的create方法
            if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                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);
        }
    }
}

2.2 ViewModel 源码分析

package androidx.lifecycle;

import androidx.annotation.MainThread;
import androidx.annotation.Nullable;

import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public abstract class ViewModel {
    //由子ViewModel负责重写
    @SuppressWarnings("WeakerAccess")
    protected void onCleared() {
    }

    //清除数据  clear方法不用主动调用,因为在ComponentActivity会通过监听Activity的生命周期
    @MainThread
    final void clear() {
        mCleared = true;
        if (mBagOfTags != null) {
            synchronized (mBagOfTags) {
                for (Object value : mBagOfTags.values()) {
                    closeWithRuntimeException(value);
                }
            }
        }
        onCleared();
    }

  	//....
    private static void closeWithRuntimeException(Object obj) {
        if (obj instanceof Closeable) {
            try {
                ((Closeable) obj).close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

三、总结

本文只是简单的介绍了ViewModel使用以及核心原理,更多关于ViewModel知识建议大家多翻翻 Android开发文档

ViewModel时序图

你可能感兴趣的:(Android技巧-源码分析)