Jetpack系列之LiveData

本文记录Jetpack之LiveData

Posted by XYH on October 4, 2018

本文记录Android JetpackArchitecture部分的LiveData以及工作原理。

Android Jetpack系列之LiveData

LiveData概述

LiveData是一个可观察数据的持有类,与常规的Observable不同,LiveData能够感知生命周期变化,他能与Activity或者FragmentService的生命周期关联,这能确保LiveData只在Activity或者Fragment生命周期处于活跃的时候刷新数据。

LiveData将一个由Observer类表示的观察者视为生命周期处于STARTED或者RESUMED状态。LiveData只会通知处于活跃状态的Observer更新数据,非活跃的Observer不会接收到通知。

注册Observer观察LiveData需要一个LifecyleOwnerLifecyleOwner是一个接口,这个LifecycleOwner状态变更为DESTROYED时候会移除与LifecycleOwner对应的Observer,通常情况下LifecycleOwner是一个Fragment或者Activity,因为在新的SupportActivityFragment都实现了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是一个包装,真正需要的是其包装的数据,通常情况下LiveDataViewModel一起使用。

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源码解析

LiveDataObserve方法入手,这是LiveDataObserver的关联入口。

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;
}

ownerLifecycleOwnerowner.getLifecycle()获取到的是LifecycleLifecycleOwner是一个接口。

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这个接口在系统中的SupportActivityFragment都有实现,这就是为什么在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;
    }
}

第一次调用getCurrentStateINITIALIZED

LiveData#observe()第二句代码。

1
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

LifecycleBoundObserverObserverWrapper的子类,何为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大致的工作流程。