Android Architecture Components源码分析

在分析Android Architecture Component这个框架之前,先想想这个框架能为我们做什么,我们为什么要按照这套框架模式去构建app?它和MVP架构有什么区别?

MVP, Clean, AAC架构的特点:
MVP架构的特点是面向接口编程。在View, Presenter, Model之间分别用接口做衔接,当有新的底层实现时,能够无缝替换。

此外,MVP的View和Model并不产生依赖,因此可以说是对View和Model做了解耦。

但MVP架构有其局限性。MVP需要创建太多的类和接口,并且每次通信都需要繁琐的通过接口传递信息

google sample提供了一个todo-mvp sample, 里面有MVP+RxJava实现,Clean架构实现。这两种架构方式我都实践过,MVP+RxJava所有业务,UI逻辑都包含在Presenter里面, Presenter直接干预了UI在拿到数据后做什么,使得逻辑上没有发生解耦,正常来说,解耦意味着Presenter的只能边界仅限返回结果数据,由UI来根据数据处理UI逻辑。

Clean架构将业务逻辑分解成可重用的更小粒度的usecase, 业务逻辑的职能被转移到领域层,Presenter则弱化为ViewModel, 作为代理数据请求和衔接数据回调的缓冲区。

Clean 架构的特点是单向依赖、数据驱动编程。 View -> ViewModel -> Usecase -> Model.

但 Clean 架构也有不足:粒度太细 。一个 Usecase 受限于请求参数,因而只能处理一类请求。View请求求的数据包含几种类型,就至少需要准备几个 Usecase。Usecase是依据当前View对数据的需求量身定制的,且形式大同小异,因此Usecase的复用率极低,项目会因而急剧的增加类和重复代码。

AAC也是数据驱动编程。直接在View中写个观察者回调,以接收结果数据并处理UI逻辑。MVP架构中Presenter直接引用View,告诉View该显示什么,而AAC中的View持有ViewModel的引用,ViewModel不需要持有View的引用,而是根据View绑定的事件进行流式调用,这也意味着MVP架构中以来的回调接口也用不着了。

数据的消费者应该知道生产者,但生产者(ViewModel)不知道也不关心谁消费了数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void subscribeUi(ProductListViewModel viewModel) {
// Update the list when the data changes
viewModel.getProducts().observe(this, new Observer<List<ProductEntity>>() {
@Override
public void onChanged(@Nullable List<ProductEntity> myProducts) {
if (myProducts != null) {
mBinding.setIsLoading(false);
mProductAdapter.setProductList(myProducts);
} else {
mBinding.setIsLoading(true);
}
// espresso does not know how to wait for data binding's loop so we execute changes
// sync.
mBinding.executePendingBindings();
}
});
}

除此之外,Fragment.setRetainInstance(boolean retain
)方法设置为true, 保证Configuration change的时候与该fragment关联的数据能够保存。

AAC是由一系列库组成,能够帮助我们管理UI组件的生命周期和处理数据存留。生命周期感知组件可以管理Activity和Fragment的生命周期,在configuration change的时候可以保留现场数据并重新更新UI,避免内存泄漏。

使用LiveData构造数据对象,当底层数据发生变化时就会通知更新UI.

ViewModel存储UI相关的数据,在app旋转时不会销毁。

Lifecycle如何与Activity, Fragment的生命周期绑定?
Lifecycle定义了一个拥有Android生命周期的对象,Activity, Fragment实现了LifecycleOwner接口,可以直接访问到Lifecycle.

1
2
3
4
5
6
7
8
9
public class ComponentActivity extends Activity
implements LifecycleOwner {

@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}

}

Lifecycle定义了两个枚举类型Event和State, State可以看做图的节点,State定义了一系列与生命周期相关的状态,Event则可以看做图的路径。Lifecycle负责保存并更新当前生命周期状态。

刚好在Activity.onDestroy()调用之前,达到DESTROYED状态,处于DESTROYED状态的Lifecycle对象不会再传递任何事件Event.

INITIALIZED状态在Lifecycle对象已创建但还未调用Activity.onCreate()之前。

在Activity.onCreate()调用之后,Activity.onStop()调用之前处于CREATED状态。

在Activity.onStart()调用之后,Activity.onPause()调用之前处于STARTED状态。

在Activity.onResume()调用之后处于RESUMED状态。

接下来看看状态的转化。

什么时候处于INITIALIZED状态呢?

首先来看一下生命周期感知组件的类关系图

Lifecycle定义成一个拥有Android生命周期的接口对象。Fragment或FragmentActivity实现了LifecycleOwner接口,并通过getLifecycle方法获取LifecycleRegistry对象。LifecycleRegistry实现了Lifecycle,能够处理多个观察者。

LifecycleRegistry定义了内部嵌套类ObserverWithState,通过调用addObserver方法我们将参数LifecycleObserver对象传入,并封装成了ObserverWithState对象,在handleLifecycleEvent接收到外部传入的Event事件,计算出目标状态,最后调用GenericLifecycleObserver的onStateChanged方法通知状态的变换。

当应用程序启动时,会注册清单文件里声明的ContentProvider, 在框架里就是ProcessLifecycleOwnerInitializer, 可以到app/build/outputs/logs/manifest-merge-debug-report.txt找到ProcessLifecycleOwnerInitializer类所在的清单文件位置,最终清单文件会合并到打包完成的应用中来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidx.lifecycle.process" >

<uses-sdk android:minSdkVersion="14" />

<application>
<provider
android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:authorities="${applicationId}.lifecycle-process"
android:exported="false"
android:multiprocess="true" />
</application>

</manifest>

ProcessLifecycleOwnerInitializer只干一件事,注册ActivityLifecycleCallbacks,具体是使用一个无UI的ReportFragment, 利用Fragment的生命周期回调将Lifecycle Event发布出去。

1
2
3
4
5
6
7
8
9
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
...
}

ProcessLifecycleOwner提供了整个应用进程的生命周期,Lifecycle.Event.ON_CREATE事件只会发布一次,而Lifecycle.Event.ON_DESTROY则不会发布。Lifecycle.Event.ON_PAUSE和Lifecycle.Event.ON_STOP事件则会在上一个Activity走完对应生命周期方法后延时发布。这个延时时间足够长,确保当configuration change导致Activity销毁,重建时不会重新发布对应事件。

当我们需要监听应用从后台回到前台或者从前台到后台时,这个类就变得很有用。
我们可以在自定义Application中添加观察者,监听到ON_START事件表示应用回到前台,监听ON_STOP事件表示应用回到了后台。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BasicApp extends Application {
private static final String TAG = BasicApp.class.getSimpleName();


@Override
public void onCreate() {
super.onCreate();

ProcessLifecycleOwner.get().getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
Log.d(TAG, "ProcessLifecycleOwner onStateChanged, event: " + event);
}
});
}
}

根据上图我们再来梳理一下ProcessLifecycleOwner发布消息的流程。
1.程序启动时,ProcessLifecycleOwner完成初始化,注册ActivityLifecycleCallbacks, 对ReportFragment设置监听器处理Fragment对应的onStart(), onResume()回调。

2.用户启动Activity, ReportFragment通过回调通知ProcessLifecycleOwner发送Lifecycle.Event.ON_START事件,并将计数器mStartedCounter加1,mStopSent置为false. 接下来收到onResume()回调,将计数器mResumedCounter加1,发送Lifecycle.Event.ON_RESUME事件,mPauseSent置为false.

3.用户启动一个新的Activity, ProcessLifecycleOwner注册的ActivityLifecycleCallbacks收到onActivityPaused回调,将计数器mResumedCounter减1,并将Lifecycle.Event.ON_PAUSE事件延时处理。如果在这段事件内configuration change导致Activity销毁并重建的话,那么计数器mResumedCounter, mStartedCounter值将发生改变,Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP事件将不会发布。当应用最后一个Activity销毁的时候,就会发布Lifecycle.Event.ON_STOP事件。

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
void activityResumed() {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else {
mHandler.removeCallbacks(mDelayedPauseRunnable);
}
}
}

void dispatchPauseIfNeeded() {
if (mResumedCounter == 0) {
mPauseSent = true;
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
}

void dispatchStopIfNeeded() {
if (mStartedCounter == 0 && mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
mStopSent = true;
}
}

FragmentActivity继承自ComponentActivity,ComponentActivity会初始化LifecycleRegistry对象并在onCreate方法里会创建一个ReportFragment. 而LifecycleDispatcher里注册的ActivityLifecycleCallbacks也会在onActivityCreated方法中初始化ReportFragment, 将这个无UI的Fragment添加到FragmentActivity中,监听activity生命周期的变化。

1
2
3
4
5
6
7
8
9
10
11
12
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component {

private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

@Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
}

Lifecycle内部定义了State和Event两个枚举类型,代表了组件所处的生命周期状态和即将变换状态的事件。下图清晰说明了状态的变化过程。

LifecycleRegistry初始化时的状态是INITIALIZED, FragmentActivity或者Fragment在生命周期方法执行时会调用handleLifecycleEvent方法完成目标状态的转换。在这个过程中,通过调用

1
mLifecycleObserver.onStateChanged(owner, 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
@Override
public void onResume() {
super.onResume();
final ProductListViewModel viewModel =
ViewModelProviders.of(this).get(ProductListViewModel.class);
subscribeUi(viewModel);
}

private void subscribeUi(ProductListViewModel viewModel) {
// Update the list when the data changes
viewModel.getProducts().observe(this, new Observer<List<ProductEntity>>() {
@Override
public void onChanged(@Nullable List<ProductEntity> myProducts) {
if (myProducts != null) {
mBinding.setIsLoading(false);
mProductAdapter.setProductList(myProducts);
} else {
mBinding.setIsLoading(true);
}
// espresso does not know how to wait for data binding's loop so we execute changes
// sync.
mBinding.executePendingBindings();
}
});
}

例如,在onResume方法中添加LifecycleBoundObserver,调用LifecycleRegistry.addObserver方法,initialState为INITIALIZED, 根据当前的状态计算出targetState为STARTED, 然后在while循环中将INITALIZED至STARTED中的所有状态依次发送出去。

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
@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);
// upEvent获取下个状态并发布
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--;
}

ObserverWrapper通过mActive标记和mLastVersion变量跟踪状态和数据的变化,对于LifecycleBoundObserver来说只有当State是STARTED才能将数据发送出去,如果State为DESTROYED状态的时候则会移除Observer. 当LiveData的version大于OberverWrapper的version时,会将最新的数据发送出去。

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