網(wǎng)站首頁 編程語言 正文
前言
我們在開發(fā)中在使用MVVM的情況下經(jīng)常會配合livedata來達到快速開發(fā)的效果,但是一般都是在activity或者fragment中去使用,我今天想介紹一種自定義的方式,如果你有復(fù)雜的自定義View或者某些場景,也可以使用livedata來達到一個很不錯的效果。
Livedata分析
我們平時使用livedata都會在activity或者fragment中使用,配合 Lifecycle就不用管理生命周期什么的了,所以一般以activity或fragment作為view層(當(dāng)然service內(nèi)也有相應(yīng)的封裝)。
viewmodel層,繼承l(wèi)ifecycler的ViewModel
var data : MutableLiveData<Int> = MutableLiveData()
fun test(){
data.value = 1
}
view層
var viewmodel = ViewModelProvider(this).get(TestViewModel::class.java)
viewmodel?. data?.observe(this, Observer {
// todo
})
一般來說就這樣寫嘛,也不用考慮注銷什么的,它自己內(nèi)部幫你實現(xiàn),很方便,but 也只能在activity或者fragment中能這樣寫
假如在view中這樣寫,傳this的地方會報錯,為什么呢,我們可以看看view層的兩個this傳的是什么。
創(chuàng)建ViewModelProvider時傳
public ViewModelProvider(@NonNull ViewModelStoreOwner owner)
調(diào)用observe方法時傳
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
可以看到一個是ViewModelStoreOwner,另一個是LifecycleOwner,并不是同一個東西
public interface ViewModelStoreOwner {
/**
* Returns owned {@link ViewModelStore}
*
* @return a {@code ViewModelStore}
*/
@NonNull
ViewModelStore getViewModelStore();
}
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
我們看看Activity內(nèi)部是怎么封裝的
public class FragmentActivity extends ComponentActivity implements
ViewModelStoreOwner,
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component
看接口的實現(xiàn)
public ViewModelStore getViewModelStore() {
......
if (mViewModelStore == null) {
......
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
return mViewModelStore;
}
看到內(nèi)部是有引用一個ViewModelStore對象
在onDestroy時
protected void onDestroy() {
super.onDestroy();
if (mViewModelStore != null && !isChangingConfigurations()) {
mViewModelStore.clear();
}
......
}
可以看出實現(xiàn)ViewModelStoreOwner接口就是持有ViewModelStore對象,并保證它的創(chuàng)建和銷毀,而它的內(nèi)部會持有viewmodel
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.
*/
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
}
那這個ViewModelStore在哪里使用呢,我們看到FragmentActivity這里只做了創(chuàng)建和銷毀,并沒有執(zhí)行put和get方法,我們深入去看可以發(fā)現(xiàn)put/get是在ViewModelProvider中調(diào)用。這也對應(yīng)了我們最初的初始化ViewModel的方法
var viewmodel = ViewModelProvider(this).get(TestViewModel::class.java)
所以很容易能看出ViewModelStore就是用來管理viewmodel的。
接下來我們看LifecycleOwner,在activity的實現(xiàn)這個接口的方法
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
看得出返回LifecycleRegistry對象,LifecycleRegistry就是Lifecycle的實現(xiàn)類,在Activity中存在調(diào)用方法
// 有很多地方有調(diào)addObserver方法
getLifecycle().addObserver(new LifecycleEventObserver() {......})
// 在這里調(diào)setCurrentState方法
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
值得注意的是LifecycleRegistry中的setCurrentState方法和handleLifecycleEvent方法
@MainThread
public void setCurrentState(@NonNull State state) {
moveToState(state);
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
看得出它們最終都是調(diào)用moveToState,調(diào)用handleLifecycleEvent只是為了把 Lifecycle.Event轉(zhuǎn)成State
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
......
}
Lifecycle的代碼就不分析了,這邊主要講Livedata。
同樣能看出FragmentActivity有調(diào)用handleLifecycleEvent
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
mFragments.dispatchCreate();
}
@Override
protected void onStart() {
......
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mFragments.dispatchStart();
}
protected void onResumeFragments() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mFragments.dispatchResume();
}
@Override
protected void onStop() {
......
mFragments.dispatchStop();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
@Override
protected void onDestroy() {
super.onDestroy();
mFragments.dispatchDestroy();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
再看看另一個LifecycleOwner的實現(xiàn),Service,這個Service叫LifecycleService
public class LifecycleService extends Service implements LifecycleOwner
它內(nèi)部引用一個ServiceLifecycleDispatcher對象,而這個對象內(nèi)部引用LifecycleRegistry。
/**
* Must be a first call in {@link Service#onCreate()} method, even before super.onCreate call.
*/
public void onServicePreSuperOnCreate() {
postDispatchRunnable(Lifecycle.Event.ON_CREATE);
}
/**
* Must be a first call in {@link Service#onBind(Intent)} method, even before super.onBind
* call.
*/
public void onServicePreSuperOnBind() {
postDispatchRunnable(Lifecycle.Event.ON_START);
}
/**
* Must be a first call in {@link Service#onStart(Intent, int)} or
* {@link Service#onStartCommand(Intent, int, int)} methods, even before
* a corresponding super call.
*/
public void onServicePreSuperOnStart() {
postDispatchRunnable(Lifecycle.Event.ON_START);
}
/**
* Must be a first call in {@link Service#onDestroy()} method, even before super.OnDestroy
* call.
*/
public void onServicePreSuperOnDestroy() {
postDispatchRunnable(Lifecycle.Event.ON_STOP);
postDispatchRunnable(Lifecycle.Event.ON_DESTROY);
}
@NonNull
public Lifecycle getLifecycle() {
return mRegistry;
}
static class DispatchRunnable implements Runnable {
private final LifecycleRegistry mRegistry;
final Lifecycle.Event mEvent;
private boolean mWasExecuted = false;
DispatchRunnable(@NonNull LifecycleRegistry registry, Lifecycle.Event event) {
mRegistry = registry;
mEvent = event;
}
@Override
public void run() {
if (!mWasExecuted) {
mRegistry.handleLifecycleEvent(mEvent);
mWasExecuted = true;
}
}
}
在外層調(diào)用
@CallSuper
@Override
public void onCreate() {
mDispatcher.onServicePreSuperOnCreate();
super.onCreate();
}
@CallSuper
@Nullable
@Override
public IBinder onBind(@NonNull Intent intent) {
mDispatcher.onServicePreSuperOnBind();
return null;
}
@SuppressWarnings("deprecation")
@CallSuper
@Override
public void onStart(@Nullable Intent intent, int startId) {
mDispatcher.onServicePreSuperOnStart();
super.onStart(intent, startId);
}
// this method is added only to annotate it with @CallSuper.
// In usual service super.onStartCommand is no-op, but in LifecycleService
// it results in mDispatcher.onServicePreSuperOnStart() call, because
// super.onStartCommand calls onStart().
@CallSuper
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@CallSuper
@Override
public void onDestroy() {
mDispatcher.onServicePreSuperOnDestroy();
super.onDestroy();
}
@Override
@NonNull
public Lifecycle getLifecycle() {
return mDispatcher.getLifecycle();
}
那么我們得出一個結(jié)論,要實現(xiàn)LifecycleOwner,主要就是自己去使用handleLifecycleEvent方法去設(shè)置生命周期。
那么這里有個問題,如果我有個Service繼承LifecycleService,它能直接快速的使用Livedata嗎,當(dāng)然不能,因為LifecycleService只實現(xiàn)了LifecycleOwner,并沒有實現(xiàn)ViewModelStoreOwner
自定義Livedata
按照上面Activity的源碼,我們知道,要實現(xiàn)Livedata,主要分為兩個步驟:
- 1. 實現(xiàn)ViewModelStoreOwner并完成ViewModelStore的創(chuàng)建和銷毀
- 2. 實現(xiàn)LifecycleOwner并手動設(shè)置生命周期其實現(xiàn)在網(wǎng)上也有很多人講在自定義View上使用Livedata,我這里就做點不同的,我在window上去實現(xiàn),其實原理都是一樣的。
class MyWindow internal constructor(val context: Context) : AbstractWindow(), LifecycleOwner,
ViewModelStoreOwner {
private var mViewModel : MyViewModel? = null
private var mViewModelStore: ViewModelStore ?= null
private val mRegistry = LifecycleRegistry(this)
fun init(){
// todo一些初始化操作
mRegistry.currentState = Lifecycle.State.CREATED
mViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
mViewModel?.data?.observe(this, Observer {
......
})
}
fun show(){
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
mWindowManager.addView(mView, getLayoutParams());
}
fun close(){
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
mWindowManager.removeViewImmediate(mView);
}
override fun getLifecycle(): Lifecycle {
return mRegistry
}
override fun getViewModelStore(): ViewModelStore {
if (mViewModelStore == null){
mViewModelStore = ViewModelStore()
}
return mViewModelStore!!
}
fun onDestroy(){
mRegistry?.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
mViewModelStore?.clear()
}
這樣就能在非activity/fragment的view層中實現(xiàn)livedata功能。
總結(jié)
自定義livedata其實沒有太大的難度,這是一個開發(fā)的過程,你想在一些地方去使用官方封裝好的框架,可以先去看看它是怎么做的,再自己進行一個二次封裝,就能實現(xiàn)那么一個效果,比如這里的自定義View或者Window使用Livadata。
原文鏈接:https://juejin.cn/post/7150488025712033822
相關(guān)推薦
- 2022-10-29 MultipartFile工具類的簡單介紹
- 2022-11-16 kali添加開機自啟的方法_相關(guān)技巧
- 2022-04-29 Sql?Server之?dāng)?shù)據(jù)類型詳解_MsSql
- 2022-12-09 深入了解Rust中泛型的使用_Rust語言
- 2022-01-18 微信小程序以post方式提交
- 2022-02-24 Antv G2折線圖+柱狀圖 自定義圖例(legend)和tooltip
- 2024-03-14 ThreadLocal使用,配合攔截器HandlerInterceptor使用
- 2022-08-19 python中的函數(shù)和變量的用法
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支