• Android  JetPack~ LiveData (一)   介绍与使用


    一般情况下LiveData都是搭配这ViewModel使用,这里先介绍一下LiveData,再结合ViewModel使用
     

    1、什么是LiveData

    1. LiveData是一个观察者模式的数据实体类,它可以在所有注册观察者回调里查看数据是否有更新。
    2. LiveData它能感知绑定者的生命周期(如Activity,Fragment),不会发生内存泄露,因为它只会给活跃状态的activity回调,我们在使用的时候通常都会在回调里去更新UI。
    3. 从非活跃状态变为活跃状态时,回调方法会立即接收到最新的数据
    4. 当设备切横竖屏,会重建Activity生命周期,它也会立即接收最新的可用数据。
    5. 不可变,setValue和postValue不支持外部使用(protected修饰)。下面代码讲解
    6. 抽象类,无法直接new
     

    2、什么是MutableLiveData

    1. MutableLiveData的父类是LiveData
    2. 用法和LiveData类似,也是在注册观察者回调里查看更新数据
    3. 可变,setValue和postValue支持外部使用(public修饰)
    4. 普通类,可以直接new
     

    3、LiveData与MutableLiveData区别

    1. LiveData在实体类里可以通知指定某个字段的数据更新.(下面会贴代码)
    2. MutableLiveData则是完全是整个实体类或者数据类型变化后才通知.不会细节到某个字段
     

    4、LiveData的使用

    public class UserBean extends LiveData {
        String name;
        int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
            postValue(this);
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
            postValue(this);
    
        }
    }
    postValue(this);这个方法是用于触发回调数据更新的方法. 你可以在你需要被观察的数据里添加.
     
    小注意点:如果不使用postValue(this)会怎么样?
        public void setAge(int age) {
            this.age = age;
    //        postValue(this);
    // 如果不写的话,单独调用setAge后,在外getAge获取不到值,因为回调没有被触发,
    // 如果name写了postValue(this),更新了name也会连着age更新,因为传的是this
        }
    你也可以集成LiveData,那么postValue(string),回调中只会接收postValue最后的赋值。
     

    4.1ViewModel新建

    public class MyViewModel extends ViewModel {
        
        public UserBean mUserBean = new UserBean();
    
        public UserBean getUserBean() {
            return mUserBean;
        }
        
    }
     

    4.2Activity中添加回调方法

    //通过ViewModeProvider 把activity和ViewModel绑定起来。
    myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
    observer = new Observer() {
        @Override
        public void onChanged(UserBean userBean) {
            Log.e("activity",userBean.getName());
            mBinding.textShow.setText("name="+userBean.getName()+"  ,, age="+userBean.getAge()+"");
        }
    };
    //绑定观察者
    myViewModel.getUserBean().observe(this, observer);
    
    a = 0;
    mBinding.btnUpdata.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myViewModel.getUserBean().setName("大王"+a);
            myViewModel.getUserBean().setAge(a++);
        }
    });
    注意:这里的myViewModel.getUserBean().observe() 是LiveData的方法。
    我们上面创建了一个Observer,并且和activity关联,然后通过一个按钮去动态设置值,果然回调里就会有数据更新。
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observersuper T> observer) {
     

    4.3有绑定就会有解绑

    myViewModel.getUserBean().removeObserver(observer);
     

    5、MutableLiveData的使用

    它是直接作用在变量上,mStr.setValue(s);触发观察者的回调。
    public class MyViewModel extends ViewModel {
        private MutableLiveData mStr;
    
        public MutableLiveData getmStr() {
            return mStr;
        }
    
        public void setmStr(String s) {
            if(mStr==null){
                mStr = new MutableLiveData<>();
            }
            mStr.setValue(s);
        }
    
    }

    5.1在activity中使用

    myViewModel.getmStr().observe(this, new Observer() {
        @Override
        public void onChanged(String s) {
            
        }
    });
     

    6、LiveData和MutableLiveData的可变与不可变

    其实就是setValue和postValue是否暴露问题,LiveData中是不支持外部使用,而MutableLiveData特意放开
    @SuppressWarnings("WeakerAccess")
    public class MutableLiveData extends LiveData {
        @Override
        public void postValue(T value) {
            super.postValue(value);
        }
    
        @Override
        public void setValue(T value) {
            super.setValue(value);
        }
    }
     
    可以看到在MutableLiveData包裹的有setValue,postValue方法
    当然我们也可以让它不对外暴露setValue,postValue方法,返回值修改为LiveData
    public class MyViewModel extends ViewModel {
        private MutableLiveData mStr= new MutableLiveData<>();
    
        public LiveData getmStr() {
            return mStr;
        }
        //在外面只能通过这种方式去更新
        public void setmStr(String s) {
            mStr.setValue(s);
    }
    }

    7、其他方法

    postValue()
      postValue的特性如下:
      1.此方法可以在其他线程中调用
      2.如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。
      3.如果同时调用 .postValue()和.setValue(),结果是post的值覆盖set值。
    
    setValue()
      setValue()的特性如下:
      1.此方法只能在主线程里调用
    getValue()
      返回当前值。 注意,在后台线程上调用此方法并不能保证将接收到最新的值。 
      
    removeObserver(@NonNull final Observersuper T> observer) 
        移除指定的观察者
        
    removeObservers(@NonNull final LifecycleOwner owner)
      移除当前Activity或者Fragment的全部观察者
      
    hasActiveObservers()
      如果此LiveData具有活动(Activity或者Fragment在前台,当前屏幕显示)的观察者,则返回true。其实如果这个数据的观察者在最前台就返回true,否则falsehasObservers()
      如果此LiveData具有观察者,则返回trueobserve(@NonNull LifecycleOwner owner, @NonNull Observersuper T> observer)
      设置此LiveData数据当前activity或者Fragment的观察者,会给此activity或者Fragment在前台时回调数据。
     
    observeForever(@NonNull Observersuper T> observer)
      1.设置永远观察者,永远不会被自动删除。您需要手动调用removeObserver(Observer)以停止观察此LiveData,
      2.设置后此LiveData,一直处于活动状态,不管是否在前台哪里都会获得回调。

    总结:

    LiveData一般使用在实体类,MutableLiveData作用在变量上,他们通常和ViewModel结合使用,上面例子过于简单,工作当中可按照业务需要进行调整。
     
  • 相关阅读:
    Selenium02
    QSS 选择器
    干货 | 身份云的云原生探索与实践:从 IAM 到 IDaaS
    使用REPLACE将数据库某一列字段进行字符串操作
    Addressable使用指南
    数据挖掘实战应用案例精讲-【概念篇】数据仓库(附实战应用案例)
    11个精美网页——Web前端开发技术课程大作业,期末考试,Dreamweaver简单网页制作
    DDIO和DMA有什么区别
    Java多线程基础(创建、使用,状态)——Java第九讲
    Redis基础特性及应用练习-php
  • 原文地址:https://www.cnblogs.com/cmusketeer/p/17121215.html