关于android:Jetpack之ViewModel

40次阅读

共计 3554 个字符,预计需要花费 9 分钟才能阅读完成。

ViewModelScope 是 viewModel 的管理者,而 ViewModelProvider 是 ViewModel 的间接管理者。
咱们个别应用的时候都是 ViewModel 持有 LiveData

应用

咱们个别获取 ViewModel 对象都是应用 ViewModelProvider 的 get()办法。
在 Activity 或者 Fragment 里调用

val  viewProvider:ViewModelProvider  = ViewModelProvider(MainActivity@this)
val viewModel:MainViewModel =  viewProvider .get(MainViewModel::class.java)

首先失去 ViewModelProvider 对象

public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
            ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
            : NewInstanceFactory.getInstance());
}

get 办法

public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
    // 取出 modelClass 的全限定名
    String canonicalName = modelClass.getCanonicalName();
    if (canonicalName == null) {throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
    }
 //  DEFAULT_KEY ="androidx.lifecycle.ViewModelProvider.DefaultKey"
   // 生成新的 Key
   return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}

最终调用

public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {ViewModel viewModel = mViewModelStore.get(key);
    if (modelClass.isInstance(viewModel)) {if (mFactory instanceof OnRequeryFactory) {((OnRequeryFactory) mFactory).onRequery(viewModel);
        }
        return (T) viewModel;
    } else {
        //noinspection StatementWithEmptyBody
 if (viewModel != null) {// TODO: log a warning.}
    }
    if (mFactory instanceof KeyedFactory) {viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
    } else {viewModel = (mFactory).create(modelClass);
    }
    mViewModelStore.put(key, viewModel);
    return (T) viewModel;
}

能够咱们传递的是一个
ViewModelStoreOwner 对象
Fragment 或者 Activity 就是这样一个对象,因为他们实现了`
ViewModelStoreOwner 接口。
就拿 Activity 的父类 ComponentActivity 来举例。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
 LifecycleOwner,
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {

它的 getViewModelStore 办法实现如下:

@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 的实现

public class ViewModelStore {
    // 一个存储 ViewModel 的 hashMap.
    private final HashMap<String, ViewModel> mMap = new HashMap<>();
    // 如果以后曾经蕴含 ViewModel 了,替换就的 ViewModel,并回调其 onCleared 办法。// 这个办法在只在 ViewModelProvieder 的 get 办法中调用,当 ViewModelProvieder 从本人的 ViewModelScore 中无奈获取 ViewModel 对象时,它会 new 一个新的,而后退出本人的 ViewModelScore 中。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);
    }
    
    Set<String> keys() {return new HashSet<>(mMap.keySet());
    }
    
    /**
 *  Clears internal storage and notifies ViewModels that they are no longer used. */ 
    public final void clear() {for (ViewModel vm : mMap.values()) {vm.clear();
        }
        mMap.clear();}
}

生命周期

ViewModel 会在 Activity Destroy 是清空本人
在 ComponentActivity 的构造方法中 Activity 会监听本人的申明周期的 ON_DESTROY 工夫。而咱们的 Activity 都继承自 ComponentActivity。

getLifecycle().addObserver(new LifecycleEventObserver() {
    @Override
 public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {if (event == Lifecycle.Event.ON_DESTROY) {// 如果是配置扭转,比方屏幕旋转等导致的销毁,不会回调 ViewModel 的 clear()办法。if (!isChangingConfigurations()) {getViewModelStore().clear();}
        }
    }
});

这样,当 Activity 销毁时,ViewModel 就能够在本人的 onCleared()办法中做一些清空数据的工作,防止的内存泄露。

正文完
 0