JetPack LiveData 使用与LiveData原理分析

一、LiveData简介

LiveData主要用于搭建MVVM架构,并在其中作为数据持有者,LiveData能监听组件的生命周期变化,这样一来只会更新处于活跃状态的组件。

LiveData的特点:
1)采用观察者模式,数据发生改变,可以自动回调(比如更新UI)。
2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据。
3)不会出现内存泄漏。
4)不需要手动取消订阅,Activity在非活跃状态下(pause、stop、destroy之后)不会收到数据更新信息

 

二、使用方法

在viewmodel 中这样使用:

public class TestViewModel extends ViewModel {

    public final MutableLiveData<TesModel> mUserLiveData = new MutableLiveData<>();

    public TestViewModel() {

        mUserLiveData.postValue(new TesModel("25"));
    }


    public void doSomething() {
        TesModel tesModel = mUserLiveData.getValue();
        if (tesModel != null) {
            mUserLiveData.setValue(tesModel);
        }
    }
}

在Activity 中这样使用:

  testViewModel.mUserLiveData.observe(this, new Observer<TesModel>() {
            @Override
            public void onChanged(TesModel tesModel) {
               
            }
        });

使用非常简单,方便,完全不用考虑更新数据的时候UI的状态

 

三、源码分析

由于 LiveData 是一个 abstract class,他的实现类MutableLiveData

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

创建了Livedata 后,需要通过observe ,这个回调接口就是Observer

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(@Nullable T t);
}
//调用上面的方法来到了LiveData的observe()方法
                        //1. 传入的是LifecycleOwner和Observer(观察者)
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    //2. 当前必须是在主线程  
    assertMainThread("observe");
    
    //3. 当前的生命周期如果是DESTROYED状态,那么不好意思,不能观察了
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    
    //4. 这里用装饰者模式将owner, observer封装起来
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    
    //5. 将观察者缓存起来
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    .....
    //6. 添加生命周期观察
    owner.getLifecycle().addObserver(wrapper);
}

首先第1点,我们传入的是Activity,到里面却看到是LifecycleOwner.看AppCompatActivity源码

​
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
        TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
//中间省略

​}
public class FragmentActivity extends ComponentActivity implements
        ViewModelStoreOwner,
        ActivityCompat.OnRequestPermissionsResultCallback,
        ActivityCompat.RequestPermissionsRequestCodeValidator {
 // 中间省略
}
public class ComponentActivity extends Activity
        implements LifecycleOwner, KeyEventDispatcher.Component {
}

AppCompatActivity的父类的父类(ComponentActivity)实现了LifecycleOwner接口,而LifecycleOwner接口是为了标识标记类有Android的生命周期的,

第2点,必须是主线程中.

第3点,如果生命周期是DESTROYED,那么不好意思,不能继续往下走了.

第4点,将owner, observer封装了起来,形成一个LifecycleBoundObserver对象

第5点我们看到有一个mObservers,它其实是LiveData里面的一个属性,是用来缓存所有的LiveData的观察者的.

我们在分析LifecycleOwner

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

在这个接口中只有一个方法用于返回Lifecycle ,Lifecycle的唯一实现类是LifecycleRegistry

public class LifecycleRegistry extends Lifecycle {
     
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();

    private final WeakReference<LifecycleOwner> mLifecycleOwner;

    // 中间省略

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
    // 中间省略
      
    }


    @Override
    public void removeObserver(@NonNull LifecycleObserver observer) {

        mObserverMap.remove(observer);
    }
   // 中间省略
   
}

主要的成员变量mObserverMap和mLifecycleOwner,mObserverMap是一个Map结构,以观察者为key存储观察者状态。mLifecycleOwner是一个弱引用,持有LifecycleOwner,其实LifecyleOwner就是Activity或者Fragment。前面说到过Activity中会实现LifecycleOwner接口,其实追踪到源码发现ComponentActivity实现了LifecycleOwner接口,由此一来LifecycleRegistry就持有Activity的弱引用了,这样一来既能监听Activity的生命周期同时也不会造成内存泄漏

回过来头来在看LifecycleBoundObserver  

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
          // 当UI的生命周期为DESTROYED,取消对数据变化的监听,移除回调函数

                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

类中封装了对于Lifecycle的状态赋值操作和状态改变对观察者进行取消订阅操作

我们继续看下activeStateChanged方法是如何对数据进行处理的,它是ObserverWrapper 类中的一个方法,

    private abstract class ObserverWrapper {
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        void activeStateChanged(boolean newActive) {
            // 当前的生命周期和上一次的生命周期状态,是否发生变化,没有发生变化,就直接返回。
            // onStart-onPause 为 true  在这之外的生命周期为false
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
           、
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
            
                onInactive();
            }

			//结合上面的状态判断,我们知道了,生命周期状态从Inactive 到 Active, 就会调用回调函数
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

 

如何得知数据已经更新

1. setValue()方式更新数据

来看LiveData的setValue()方法

private volatile Object mData = NOT_SET;
protected void setValue(T value) {
    assertMainThread("setValue");
    mVersion++;
    mData = value;
    dispatchingValue(null);
}

首先是当前必须是主线程,然后将值保存到了mData属性中.

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    ......
    //遍历所有的观察者执行considerNotify()方法
    for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
            mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
        considerNotify(iterator.next().getValue());
    }
    ......
}
private void considerNotify(ObserverWrapper observer) {
    ......
    observer.mObserver.onChanged((T) mData);
}

2. postValue()方式更新数据

volatile Object mPendingData = NOT_SET;

private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //noinspection unchecked
        //最后还是调用的setValue()嘛
        setValue((T) newValue);
    }
};


protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

将value值赋值给mPendingData,然后通过ArchTaskExecutor的实例将mPostValueRunnable传入postToMainThread()方法.

ArchTaskExecutor 怎么处理的

public static ArchTaskExecutor getInstance() {
    if (sInstance != null) {
        return sInstance;
    }
    synchronized (ArchTaskExecutor.class) {
        if (sInstance == null) {
            sInstance = new ArchTaskExecutor();
        }
    }
    return sInstance;
}

private ArchTaskExecutor() {
    mDefaultTaskExecutor = new DefaultTaskExecutor();
    mDelegate = mDefaultTaskExecutor;
}

public class DefaultTaskExecutor extends TaskExecutor {
    @Nullable
    private volatile Handler mMainHandler;
    
    @Override
    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }
}

通过ArchTaskExecutor里面的DefaultTaskExecutor里面的postToMainThread()方法,其实将mPostValueRunnable交给了一个mMainHandler,这个mMainHandler有主线程的looper.可以方便的将Runnable搞到主线程. 所以最后mPostValueRunnable会到主线程中执行setValue(),毫无问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值