本文记录Android Jetpack中
Architecture部分的LiveData以及工作原理。
Android Jetpack系列之LiveData
LiveData概述
LiveData是一个可观察数据的持有类,与常规的Observable不同,LiveData能够感知生命周期变化,他能与Activity或者Fragment、Service的生命周期关联,这能确保LiveData只在Activity或者Fragment生命周期处于活跃的时候刷新数据。
LiveData将一个由Observer类表示的观察者视为生命周期处于STARTED或者RESUMED状态。LiveData只会通知处于活跃状态的Observer更新数据,非活跃的Observer不会接收到通知。
注册Observer观察LiveData需要一个LifecyleOwner,LifecyleOwner是一个接口,这个LifecycleOwner状态变更为DESTROYED时候会移除与LifecycleOwner对应的Observer,通常情况下LifecycleOwner是一个Fragment或者Activity,因为在新的SupportActivity、Fragment都实现了LifeCycleOwner接口。有了这种对应关系就不用再担心操作发生内存泄漏了。
1
2
3
4
5
6
7
8
9
10
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
liveData.observe(this, Observer {
})
}
}
使用LiveData的优点
-
确保UI更新符合数据状态
LiveData遵循观察者模式,Observer生命周期状态更改时LiveData会通知对应的Observer,每次LiveData数据更改时,对应的观察者可以在每次更新时更新UI。 -
没有内存泄漏
Observer绑定的LifecycleOwner对象在LifecycleOwner销毁时自动解除绑定。 -
不会再有由于
ActivityStop时引起的crash 如果Observer的生命周期处于非活跃状态,例如Activity退到后台,那Observer不会再接收到LiveData的数据更新。 -
不需要手动处理生命周期 UI组件只观察与其有关的数据,不会自动停止、恢复观察对应数据,
LiveData自动管理这些,因为它会跟这些生命周期联动。 -
始终保持最新数据 如果生命周期变为非活动状态,则会在再次变为活动状态时接收最新数据。例如,后台活动在返回前台后立即收到最新数据。
-
更好的处理配置更改 如果
Activity或者Fragment由于配置发生改变而重新OnCreate,如屏幕旋转,Observer接收到的始终是最新数据。 -
资源共享 我们可以使用单例模式来扩展
LiveData然后包装系统服务,然后在应用内这个LiveData是共享的。
使用LiveData
创建LiveData对象
LiveData是一个包装,真正需要的是其包装的数据,通常情况下LiveData与ViewModel一起使用。
1
2
3
4
5
6
7
8
9
10
class NameViewModel : ViewModel() {
var names: MutableLiveData<List<String>>? = null
private set
get() {
if (field == null) {
field = MutableLiveData()
}
return field
}
}
观察LiveData对象
在大多数情况,在onCreate中观察LiveData是最好的,因为避免了onResume的重复调用,同时确保Activity或者Fragment能在处于活跃状态时立即显示数据,只要应用组件处理STARTED状态,它就会从LiveData观察的对象中获取最近值。
此外,LiveData只有在数据更改,并且只有处于活跃的Observer才能接收到更新。不过有一个例外,当Observer从非活跃状态变更改活跃状态时也会接受到更新。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mNameViewModel = ViewModelProviders.of(this)
.get(NameViewModel::class.java)
val namesTv = findViewById<TextView>(R.id.tv_names)
mNameViewModel.names?.observe(this, Observer {
namesTv.text = it.toString()
})
}
}
更新LiveData对象
LiveData没有公开的方法更新持有的数据,只有MutableLiveData提供了setValue(T)和postValue(T)用于更新持有的数据,setValue(T)必须在主线程中调用,而postValue(T)可以在子线程中调用,通常MutableLiveData用于ViewModel然后将ViewModel唯一的不可变LiveData对象暴露给观察者。
更新LiveData中的对象的值。
1
2
3
4
5
6
7
8
9
findViewById<Button>(R.id.btn_update).apply {
setOnClickListener {
mNameViewModel.names?.value = ArrayList<String>().apply {
add("Anna")
add("Bruce")
add("qfxl")
}
}
}
调用setValue(T)会回调观察者的onChanged(T)方法。
扩展LiveData
LiveData可以看做一个观察者,如果观察者的状态为STARTED或者RESUMED的时候可以认为LiveData正处于活跃的状态。
下面是一个模拟股票刷新的实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class StockLiveData : LiveData<BigDecimal>() {
private object Holder {
val INSTANCE = StockLiveData()
}
companion object {
fun get(): StockLiveData {
return Holder.INSTANCE
}
}
private val dispatcherHandler = Handler(Looper.getMainLooper())
private val updateRunnable = Runnable {
value = BigDecimal.valueOf(Random().nextInt(2500).toLong())
updateStockData()
}
override fun onActive() {
updateStockData()
}
override fun onInactive() {
dispatcherHandler.removeCallbacks(updateRunnable)
}
private fun updateStockData() {
dispatcherHandler.postDelayed(updateRunnable, 1000)
}
}
使用:
1
2
3
4
5
6
7
8
9
10
11
12
class StockActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_stock)
val stockTv = findViewById<TextView>(R.id.tv_stock)
val liveData = StockLiveData.get()
liveData.observe(this, Observer {
stockTv.text = "上证指数 $it"
})
}
}
在Activity不可见的时候自动解除绑定关系,在重新可见的时候会重新绑定。
//TODO 效果图
在上述示例中实现了几个比较重要的方法:
onActive方法当LiveData有观察者的时候,可以在这个方法进行数据更新操作。onInActive方法当LiveData观察者从N-0的时候调用,就是当LiveData没有观察者的时候会被调用。setValue(T)用于更新LiveData持有的对象数据。
转换LiveData
有时候我们需要将LiveData持有的对象进行转换,比如LiveData原先持有的是一个User但是我想要的只有其中的name属性,这样就可以用到Lifecycle中提供的Transformations。
Transformations.map()
1
2
3
4
5
6
val userLiveData = UserLiveData()
Transformations.map(userLiveData) {
it.name
}.observe(this, Observer {
stockTv.text = it
})
Transformations.switchMap()
类似于map()但是需要返回一个LiveData
1
2
3
4
5
private fun getUser(id: String): LiveData<User> {
...
}
val userId: LiveData<String> = ...
val user = Transformations.switchMap(userId) { id -> getUser(id) }
以上为LiveData的基本用法。
LiveData源码解析
从LiveData的Observe方法入手,这是LiveData跟Observer的关联入口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
LiveData#observe()第一句代码。
1
2
3
4
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
owner为LifecycleOwner,owner.getLifecycle()获取到的是Lifecycle,LifecycleOwner是一个接口。
1
2
3
4
5
6
7
8
9
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
Lifecycle是一个抽象类,它只有一个已知子类LifecycleRegistry。
getLifecycle().getCurrentState()返回的是一个枚举值,它定义在Lifecycle中,每个枚举的意思都有详细的英文注释文档。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public enum State {
/**
* Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch
* any more events. For instance, for an {@link android.app.Activity}, this state is reached
* <b>right before</b> Activity's {@link android.app.Activity#onDestroy() onDestroy} call.
*/
DESTROYED,
/**
* Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is
* the state when it is constructed but has not received
* {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet.
*/
INITIALIZED,
/**
* Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
* <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call.
* </ul>
*/
CREATED,
/**
* Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {@link android.app.Activity#onStart() onStart} call;
* <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.
* </ul>
*/
STARTED,
/**
* Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached after {@link android.app.Activity#onResume() onResume} is called.
*/
RESUMED;
/**
* Compares if this State is greater or equal to the given {@code state}.
*
* @param state State to compare with
* @return true if this State is greater or equal to the given {@code state}
*/
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
owner.getLifecycle().getCurrentState()这句代码需要到LifecycleOwner实现类中去找对应方法,LifecycleOwner这个接口在系统中的SupportActivity、Fragment都有实现,这就是为什么在Activity/Fragment中调用LiveData#Observe()方法中可以传入this。
以SupportActivity为例,它是Activity的直接子类,并且实现了LifecycleOwner。
1
2
3
4
5
6
7
8
9
10
public class SupportActivity extends Activity implements LifecycleOwner {
xxx
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
xxx
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
xxx
}
owner.getLifecycle().getCurrentState()最终调用的地方为LifecycleRegistry#getCurrentState(),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class LifecycleRegistry extends Lifecycle {
xxx
private final WeakReference<LifecycleOwner> mLifecycleOwner;
/**
* Current state
*/
private State mState;
xx
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
@Override
public State getCurrentState() {
return mState;
}
}
第一次调用getCurrentState为INITIALIZED。
LiveData#observe()第二句代码。
1
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
LifecycleBoundObserver是ObserverWrapper的子类,何为ObserverWrapper?顾名思义是Observer的包装类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private abstract class ObserverWrapper {
final Observer<T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<T> observer) {
mObserver = observer;
}
/**
* 需要实现的方法,是否是活跃状态。
*/
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
/**
* 状态更改
*/
void activeStateChanged(boolean newActive) {
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();
}
if (mActive) {
dispatchingValue(this);
}
}
}
点开LifecycleBoundObserver,它实现了GenericLifecycleObserver接口,这个在分析LifecycleRegistry#addObserver(LifecycleObserver)会用到。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<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) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LiveData#observe()第三句代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
// private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers =
// new SafeIterableMap<>();
//如果存在则直接返回,否则put到mObservers中。
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//如果当前的ObserverWrapper不为空,并且当前传入的LifecycleOwner与ObserverWrapper原先的LifecycleOwner不一致的时候抛出异常。
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//如果当前的ObserverWrapper不为空,则不进行任何操作。
if (existing != null) {
return;
}
LiveData#observe()最后一句代码
1
owner.getLifecycle().addObserver(wrapper);
经过了上面分析,可知这句代码最后调用的地方为LifecycleRegistry#addObserver(LifecycleObserver)。这个方法有一堆计算State方法以及EVENT转换STATE的操作,虽然多但是不复杂。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
//最重要的是这句,这里回将Event回调出去 statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
上面代码中出现了一个ObserverWithState。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
//根据Event返回State,Event也是一个枚举,其中有ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY
State newState = getStateAfter(event);
//计算当前的State
mState = min(mState, newState);
//回调Event mLifecycleObserver.onStateChanged(owner, event);
//将新的State赋值给mState
mState = newState;
}
}
LiveData#Observe()方法的大致流程至此。下面跟踪LiveData#setValue(T),这个方法要求在主线程中调用,如果想在子线程中更新LiveData的值,可以调用LiveData#postValue(T),下面是LiveData#setValue(T)的代码:
1
2
3
4
5
6
7
8
9
10
@MainThread
protected void setValue(T value) {
//判断当前线程是否是主线程,不是则会抛出异常
assertMainThread("setValue");
//这个版本在后文的considerNotify中用于判断是否要回调Observerde#onChagned()
mVersion++;
//记录此次的数据
mData = value;
dispatchingValue(null);
}
dispatchingValue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
//前面都是一些变量的控制
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//这里调用considerNotify considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
considerNofify
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
//这里回调了Observer的onChanged()方法
observer.mObserver.onChanged((T) mData);
}
LiveData的状态在何时改变
调用状态改变的入口在LifecycleRegistry#handleLifecycleEvent,这个方法在supportActvity中有这么一句代码。
1
2
3
4
5
6
@Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
onCreate的时候会调用ReportFragment.injectIfNeededIn(this);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
//这里改变LiveData的STATE
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
// just want to be sure that we won't leak reference to an activity
mProcessListener = null;
}
以上就是LiveData大致的工作流程。