# viewmodel_for_ohos **Repository Path**: ethan-osc_admin/viewmodel_for_ohos ## Basic Information - **Project Name**: viewmodel_for_ohos - **Description**: 移植自安卓的ViewModel和LiveData,可以在鸿蒙系统上使用,此外为了移植这两个库,还移植了附带的一些安卓基础库 - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-09-02 - **Last Updated**: 2023-06-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: HarmonyOS组件 ## README # viewmodel_for_ohos #### 介绍 移植自安卓的ViewModel和LiveData,可以在鸿蒙系统上使用,此外为了移植这两个库,还移植了附带的一些安卓基础库 本库的ViewModel和LiveData代码基于androidx.life.xxx的2.2.0版本移植而来 #### 使用说明 该库已经提交到MavenCenter里面,可以通过: ``` implementation 'io.gitee.ethan-osc_admin:ohos_viewmodel_livedata:2.2.0' ``` 安卓里面,之所以可以使用ViewModel和LiveData,是因为Activity和Fragment都继承了LifeCycleOwner,ViewModelStoreOwner和HasDefaultViewModelProviderFactory,而鸿蒙里面Ability和Slice只实现了ILifecycle,所以笔者参照Android的代码,自定义了CompatAbility,和CompatSlice,使用ViewModel和LiveData需要继承这两个基础类 ``` public class CompatSlice extends AbilitySlice implements ViewModelStoreOwner, HasDefaultViewModelProviderFactory { ...... } public class CompatAbility extends Ability implements ViewModelStoreOwner, HasDefaultViewModelProviderFactory { ...... } ``` 因为鸿蒙里,使用了Ability为承载单元,Slice为子类单元(类似于谷歌推荐的一个Activity,多个Fragment的方式),所以主要验证这种场景下ViewModel和LiveData是否工作正常 ``` public class NoteViewModel extends ViewModel { public MutableLiveData> notes = new MutableLiveData<>(); public void fetchNotes() { notes.setValue(NoteModel.fetchNotes()); } public void fetchGlobalNotes() { notes.setValue(NoteModel.fetchGlobalNotes()); } } //用法和Android一样,然后定义个辅助类,验证数据 public class NoteModel { public String content; public String modifyTime; private NoteModel(String content, String modifyTime){ this.content = content; this.modifyTime = modifyTime; } public static List fetchNotes(){ List noteModels = new ArrayList<>(); noteModels.add(new NoteModel("这是一个普通内容","2021-03-31")); return noteModels; } public static List fetchGlobalNotes(){ List noteModels = new ArrayList<>(); noteModels.add(new NoteModel("this is 全局Life","2021-08-31")); return noteModels; } } //调用示例主要片段: public class LifeAbilitySlice extends CompatSlice { private static final String TAG = "LifeAbilitySlice"; private NoteViewModel vm; private NoteViewModel globalVm; @Override protected void onStart(Intent intent) { super.onStart(intent); setUIContent(ResourceTable.Layout_life_request_layout); LifeAbilitySlice2 life2 = new LifeAbilitySlice2(); findComponentById(ResourceTable.Id_btn_life).setClickedListener(component -> { vm.fetchNotes(); }); findComponentById(ResourceTable.Id_btn_life_global).setClickedListener(component -> { globalVm.fetchGlobalNotes(); }); findComponentById(ResourceTable.Id_btn_to_life2).setClickedListener(component -> { present(life2,new Intent()); }); initSliceViewModel(); initGlobalViewModel(); } //验证本Slice中的事件响应 private void initSliceViewModel(){ ViewModelProvider provider = ViewModelProviders.of(this); vm = provider.get(NoteViewModel.class); Log.d(TAG, "slice vm addr:" + vm); vm.notes.observe(this, noteModels -> { Log.d(TAG, "noteModels:" + noteModels.get(0).content); }); } //验证基于所依赖的Ability的事件响应,经常出现的场景是多个Slice公有一个Ability的情况 private void initGlobalViewModel(){ ViewModelProvider globalProvider = ViewModelProviders.of((CompatAbility) getAbility()); globalVm = globalProvider.get(NoteViewModel.class); Log.d(TAG, "global vm addr:" + globalVm); globalVm.notes.observe(this, noteModels -> { Log.d(TAG, "global noteModels:" + noteModels.get(0).content); }); } } ``` #### 与安卓不同的改动点 1.安卓中交LifeCycleOwner,鸿蒙中叫ILifecycle,用以感知生命周期 2.Lifecycle EVENT安卓里和State是分开的,而鸿蒙里是合并了,发生了EVENT代表了置为了相应状态 3.修改了一个比较重要的函数 boolean shouldBeActive() { //和安卓有所区别,安卓是Event和State分开的,而鸿蒙是放一起的,这里的本意是判断 //页面是否是判断页面是否已经将要显示,或者已经显示,对应的安卓状态是started和resume //而鸿蒙里面对应的状态是 ON_ACTIVE return mOwner.getLifecycle().getLifecycleState().compareTo(Lifecycle.Event.ON_ACTIVE) == 0; } Live事件可以通知依赖于这个函数返回true,然后再分发事件 4.鸿蒙的生命周期状态少于安卓,但是基本能对应上,记住几个常用的: 安卓 : 鸿蒙 onCreate:on_start onResume:on_active onStart:on_active onDestory:on_stop 5.移植的时候,放弃了SavedStateViewModelFactory,这个类的本意是创建的Factory存入Map,以便后面可以复用,由于代码比较复杂,所涉及的安卓库较多,放弃了移植,不过目前根据Demo看来,ViewModel和LiveData的功能都正常 6.LiveData做了一点修改,Observe的时候,在全局模式的时候,刚创建的Slice2在刚创建的时候会收到之前的Value更新的信息,这个也是安卓使用者,Activity对应多个Fragment中数据串扰的痛点所在,所以本库在保证原汁原味的安卓大部分的代码下,做了创新,多了一个observeNoStick接口,意思创建后,不接收过去的任何信息。避免共享的时候,数据串扰