這篇文章主要介紹“ViewModel如何使用”,在日常操作中,相信很多人在ViewModel如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”ViewModel如何使用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
1 主要功能
Activity、Fragment存活期間的數(shù)據(jù)存儲(chǔ);
bind同一Activity的多個(gè)Fragment間數(shù)據(jù)共享;
獨(dú)立或與LiveData配合實(shí)現(xiàn)代碼解耦;
1) 引入ViewModel
在build.gradle中添加編譯lifecycle.extensions module,該module同時(shí)包含ViewModel和LiveData:
compile('android.arch.lifecycle:extensions:1.0.0')
由于lifecycle.extensions內(nèi)部依賴26.1.0版本的support_v7包,建議將工程中已引用的support_v7組件版本也升級(jí)到26.1.0或以上。
2) 構(gòu)造數(shù)據(jù)對(duì)象
自定義ViewModel類,繼承ViewModel;
在自定義的ViewModel類中添加需要的數(shù)據(jù)對(duì)象;
public class DemoViewModel extends ViewModel { final public DemoData mData = new DemoData(); public DemoViewModel() {} }
3) 獲取數(shù)據(jù)
通過ViewModelProviders和Activity / Fragment獲取ViewModelProvider;
通過ViewModelProvider和自定義ViewModel類獲取自定義ViewModel對(duì)象;
從自定義ViewModel對(duì)象獲取數(shù)據(jù)對(duì)象,進(jìn)行需要的讀寫操作。
DemoData data = ViewModelProviders.of(getActivity()) .get(DemoViewModel.class) .mData; data.doSth();
需求點(diǎn):
bind同一個(gè)Activity的Fragment A、B;
Fragment A、B間存在跳轉(zhuǎn)關(guān)系;
Fragment A、B共同維護(hù)一些數(shù)據(jù),且A、B均有讀取、修改的業(yè)務(wù)需求;
傳統(tǒng)實(shí)現(xiàn)方法1:Intent +onFragmentResult()
大致流程:
跳轉(zhuǎn)時(shí)需要將數(shù)據(jù)按k-v封裝入Bundle,或者將數(shù)據(jù)Parcelable傳遞給下個(gè)頁面;
下個(gè)頁面修改數(shù)據(jù)并返回后,需要從onFragmentResult()的Intent解析并同步數(shù)據(jù);
Intent傳遞的數(shù)據(jù)大小總量不能超過1M;
麻煩且數(shù)據(jù)大小有限制。
傳統(tǒng)實(shí)現(xiàn)方法2:數(shù)據(jù)對(duì)象SingleInstance、static
缺點(diǎn):
數(shù)據(jù)的生命周期要自行控制;
容易內(nèi)存泄漏;
同樣麻煩,且有一定風(fēng)險(xiǎn)。
ViewModel同時(shí)規(guī)避了傳統(tǒng)方法的缺點(diǎn):
bind同一個(gè)Activity的Fragments均可以通過ViewModelProvider獲取共同的數(shù)據(jù)對(duì)象,無需主動(dòng)進(jìn)行數(shù)據(jù)傳遞;
脫離Intent、Bundle、Parcelable這些用起來很麻煩的控件;
數(shù)據(jù)生命周期由ViewModel內(nèi)部掌控,無需手動(dòng)管理銷毀;
同為官方架構(gòu)組件的LiveData,功能是監(jiān)聽數(shù)據(jù)變化,并回調(diào)給注冊(cè)的observer。ViewModel+LiveData可以很方便的抽象出數(shù)據(jù)層和業(yè)務(wù)層,快速解耦。
下面的Demo來自官方案例。通過Demo,以及LiveData、ViewModel同處一個(gè)module,可以看出官方非常建議兩者搭配使用。再配合以往的Data-Binding,可以快速搭建起一套簡易的MVVM業(yè)務(wù)體系。
public class MyViewModel extends ViewModel { private MutableLiveData<List<User>> users; public LiveData<List<User>> getUsers() { if(users == null) { users= new MutableLiveData<List<Users>>(); loadUsers(); } return users; } private void loadUsers() { //Do an asyncronous operation to fetch users. } } public class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { //Create a ViewModel the first time the system calls an activity's onCreate()method. //Re-created activities receive the same MyViewModel instance created by thefirst activity. MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); model.getUsers().observe(this,users -> { //update UI }); } }
ViewModel的生命周期與Lifecycle同步,當(dāng)Activity /Fragment超出Lifecycle范圍(并不是onDestroy()回調(diào)),ViewModel連同其包含的數(shù)據(jù)一起被銷毀了。具體有多大呢,按照官方說法:
in the case of an activity, when it finishes, whilein the case of a fragment, when it’s detached.
Activity退棧后(Fragment則是與Activity解除關(guān)系后),ViewModel就解除引用關(guān)系,準(zhǔn)備被系統(tǒng)回收了。
帶著兩個(gè)小問題簡單的進(jìn)行下源碼分析:
第一部分:獲取ViewModelProvider
調(diào)用ViewModelProviders.of(Activity);
一路調(diào)用,最終走到HolderFragmentManager.holderFragmentFor(Activity);
HolderFragmentManager依次從FragmentManager和HolderFragmentManager持有的HashMap查找:該Activity是否有HolderFragment與之映射(HolderFragment的作用下面一個(gè)問題將談到);
HolderFragment.class HolderFragment holderFragmentFor(FragmentActivity activity) { FragmentManagerfm = activity.getSupportFragmentManager(); HolderFragment holder = findHolderFragment(fm); if(holder != null) { return holder; }else { holder = (HolderFragment)this.mNotCommittedActivityHolders.get(activity); if(holder != null) { return holder; }else { //創(chuàng)建HolderFragment
有則返回該HolderFragment;沒有則創(chuàng)建一個(gè)HolderFragment:
新建一個(gè)HolderFragment,commit給FragmentManager,并存入HashMap以標(biāo)記為not committed狀態(tài),防止重復(fù)commit;
向Application注冊(cè)對(duì)該Activity的生命周期監(jiān)聽。如果HolderFragment尚未create,Activity就已經(jīng)銷毀,則從HashMap中移除該Activity,防止泄露;
HolderFragment成功創(chuàng)建后,從HashMap中移除該Activity;
使用HolderFragment持有的ViewModelStore對(duì)象完成ViewModelProvider的創(chuàng)建;
第一部分的職責(zé)是構(gòu)建 / 查找HolderFragment,對(duì)構(gòu)建過程中的異常做保護(hù),最后返回ViewModelProvider。HolderFragment和ViewModelProvider共同持有的ViewModelStore將成為第二部分的核心;
(第二部分:獲取ViewModel)
調(diào)用ViewModelProvider.get(ViewModel.class);
通過ViewModel的規(guī)范名(canonical name),從HashMap中查找是否已經(jīng)存在該ViewModel的實(shí)例。有則返回;沒有則通過反射構(gòu)建一個(gè),并存入HashMap;
ViewModelStore.class public class ViewModelStore { private final HashMap<String, ViewModel> mMap = new HashMap();
第二部分職責(zé)是映射,通過類名從HashMap查找ViewModel實(shí)例。整個(gè)映射邏輯也可以簡化為:通過Activity類名找ViewModel實(shí)例;
ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel.
看到官方文檔中的這句話,心想ViewModel莫非是通過同為官方架構(gòu)組件的Lifecycle來管理的生命周期的?
其實(shí)并沒有那么復(fù)雜,ViewModel在第一次調(diào)用ViewModelProvider.get(ViewModel.class)創(chuàng)建;而銷毀就需要靠HolderFragment自己的onDestroy()回調(diào):
HolderFragment.class public void onDestroy() { super.onDestroy(); this.mViewModelStore.clear(); }
ViewModelStore.class public final void clear() { Iteratorvar1 = this.mMap.values().iterator(); while(var1.hasNext()){ ViewModel vm = (ViewModel)var1.next(); vm.onCleared(); } this.mMap.clear(); }
HolderFragment銷毀后,調(diào)用ViewModelStore.clear(),清理HashMap對(duì)ViewModel對(duì)象的引用,待系統(tǒng)GC回收ViewModel。這也解釋了創(chuàng)建ViewModelProvider時(shí)為什么需要HolderFragment配合,HolderFragment掌控了ViewModel的生命周期。
簡述下官方架構(gòu)中各組件的主要職責(zé):
Lifecycle:將Activity /Fragment生命周期回調(diào)事件向外拋出;
LiveData:在Lifecycle范圍內(nèi)監(jiān)聽數(shù)據(jù)的變化;
ViewModel:在Lifecycle范圍內(nèi)存儲(chǔ)和共享數(shù)據(jù);
Room:簡化Db操作;
除了Room,可以感受到官方在盡力把大家從最初的MVC往MVVM引導(dǎo),更加強(qiáng)大的官方組件將使UI-業(yè)務(wù)-數(shù)據(jù)的抽象過程變得更加簡單順滑。
到此,關(guān)于“ViewModel如何使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
當(dāng)前標(biāo)題:ViewModel如何使用-創(chuàng)新互聯(lián)
本文來源:http://chinadenli.net/article0/cdpcoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、企業(yè)建站、企業(yè)網(wǎng)站制作、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容