-
Notifications
You must be signed in to change notification settings - Fork 121
UnPeekLiveData v7 设计思路
KunMinX edited this page Jun 13, 2022
·
10 revisions
以下源码设计,及对设计思路理解和解析,属于参与过源码设计讨论有效贡献者及本人共同成果,我们对此享有所有权和最终解释权。
任何个人或组织在引用以下内容时,须注明原作者和链接出处。未经授权不得用于洗稿、广告包装、卖课等商业用途。
Copyright 2019-present KunMinX
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
package com.example.roomdemo.livedatabus;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/**
* TODO V7 版源码来自小伙伴 RebornWolfman 在 issue 中分享,
* https://github.com/KunMinX/UnPeek-LiveData/issues/17
*/
public class SimplePeekLiveData<T> extends LiveData<T> {
private final AtomicInteger currentVersion = new AtomicInteger(-1);
@Override
public void observe(@NonNull @NotNull LifecycleOwner owner, @NonNull @NotNull Observer<? super T> observer) {
super.observe(owner, createObserverWrapper(observer, currentVersion.get()));
}
@Override
public void observeForever(@NonNull @NotNull Observer<? super T> observer) {
super.observeForever(createObserverWrapper(observer, currentVersion.get()));
}
@Override
public void setValue(T value) {
currentVersion.getAndIncrement();
super.setValue(value);
}
@Override
public void postValue(T value) {
currentVersion.getAndIncrement();
super.postValue(value);
}
/**
* 添加一个包装类,添加一个版本号判断
* 重写equals方法和hashCode 忽略版本号的判断,
* 好处1:那么在removeObserver的时候只需要传入你实际创建的Observer那么就不需要添加集合来自己缓存
* 好处2:就是你在添加监听的时候也是不需要自己去重复,源码livedata里面已经有了判断
*/
class ObserverWrapper implements Observer<T> {
private final Observer<? super T> observer;
private int mVersion = -1;
public ObserverWrapper(@NotNull Observer<? super T> observer, int mVersion) {
this.observer = observer;
this.mVersion = mVersion;
}
@Override
public void onChanged(T t) {
if (currentVersion.get() > mVersion) {
observer.onChanged(t);
}
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ObserverWrapper that = (ObserverWrapper) o;
return Objects.equals(observer, that.observer);
}
@Override
public int hashCode() {
return Objects.hash(observer);
}
}
private ObserverWrapper createObserverWrapper(@NonNull @NotNull Observer<? super T> observer, int version) {
//FIXME 注:此处或引入内存泄漏隐患,修复方案有 v7.1 和 v7.2 两种,后续皆采用 v7.2 方案。
return new ObserverWrapper(observer, version);
}
@Override
public void removeObserver(@NonNull @NotNull Observer<? super T> observer) {
super.removeObserver(createObserverWrapper(observer, -1));
}
}