本文记录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
销毁时自动解除绑定。 -
不会再有由于
Activity
Stop
时引起的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
大致的工作流程。