Google 为了帮助 Android 开发者更快更好地开发 App,推出了一系列组件,这些组件被打包成了一个整体,称作 Android Jetpack,它包含的组件如下图所示
官方对应 Architecture 的说明:
Android architecture components are a collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.
Manage your app’s lifecycle with ease. New lifecycle-aware components help you manage your activity and fragment lifecycles. Survive configuration changes, avoid memory leaks and easily load data into your UI.
Use LiveData to build data objects that notify views when the underlying database changes.
ViewModel Stores UI-related data that isn’t destroyed on app rotations.
Room is an a SQLite object mapping library. Use it to Avoid boilerplate code and easily convert SQLite table data to Java objects. Room provides compile time checks of SQLite statements and can return RxJava, Flowable and LiveData observables.
翻译:
Android体系结构组件是一组库,可帮助您设计健壮,可测试和可维护的应用程序。 从用于管理UI组件生命周期和处理数据持久性的类开始。
轻松管理应用程序的生命周期。 新的生命周期感知组件可帮助您管理活动和碎片生命周期。 生存配置更改,避免内存泄漏并轻松将数据加载到UI中。
使用LiveData构建数据对象,以便在基础数据库更改时通知视图。
ViewModel存储在应用程序轮换中未销毁的UI相关数据。
Room是一个SQLite对象映射库。 使用它来避免样板代码并轻松地将SQLite表数据转换为Java对象。 Room提供SQLite语句的编译时检查,可以返回RxJava,Flowable和LiveData observable。
#####官方推荐的应用架构指南
常见架构原则
1.分离关注点
要遵循的最重要的原则是分离关注点一种常见的错误是在一个 Activity 或 Fragment中编写所有代码。这些基于界面的类应仅包含处理界面和操作系统交互的逻辑。应尽可能使这些类保持精简,这样可以避免许多与生命周期相关的问题。
请注意,您并不拥有 Activity 和 Fragment的实现,这些只是表示 Android 操作系统与应用之间关系的粘合类。操作系统可能会根据用户交互或因内存不足等系统条件随时销毁它们。为了提供令人满意的用户体验和更易于管理的应用维护体验,最好尽量减少对它们的依赖。
2.用过模型驱动界面
另一个重要原则是您应该通过模型驱动界面,最好是持久性模型。模型是负责处理应用数据的组件。它们独立于应用中的 View 对象和应用组件,因此不受应用的生命周期以及相关关注点的影响。
持久性是理想之选,原因如下
应用所基于的模型类应明确定义数据管理职责,这样将使应用更可测试且更一致。
看下图,该图显示了设计应用后所有模块应如何交互
请注意,每个组件仅依赖于其下一级的组件。例如,Activity 和 Fragment 仅依赖于视图模型。存储区是唯一一个依赖于其他多个类的类;在本例中,存储区依赖于持久性数据模型和远程后端数据源。
这种设计打造了一致且愉快的用户体验。无论用户是在上次关闭应用几分钟后还是几天后回到应用,他们都会立即看到应用在本地保留的用户信息。如果此数据已过时,则应用的存储区模块将开始在后台更新数据。
ViewModel类旨在以生命周期意识的方式存储和管理与UI相关的数据。 ViewModel类允许数据在配置更改(例如屏幕旋转)后继续存在。
示例代码
public class FlowerModel extends ViewModel {
private MutableLiveData liveData;
public MutableLiveData getLiveData() {
if (liveData == null){
liveData = new MutableLiveData<>();
}
return liveData;
}
public static class Data {
public int send;
public int less;
public List list;
}
}
flowerModel = ViewModelProviders.of(getActivity()).get(FlowerModel.class);
然后利用LiveData通知界面更新UI
LiveData 是一种可观察的数据存储器。应用中的其他组件可以使用此存储器来监控对象的更改,而无需在它们之间创建明确且严格的依赖路径。LiveData 组件还遵循应用组件(如 Activity、Fragment 和 Service)的生命周期状态,并包括清理逻辑以防止对象泄漏和过多的内存消耗。
flowerModel.getLiveData().observe(getActivity(), new Observer() {
@Override
public void onChanged(@Nullable FlowerModel.Data data) {
//update UI
}
});
Demo演示
ViewModel生命周期
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return of(fragment, null);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return of(activity, null);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
Application application = checkApplication(checkActivity(fragment));
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(ViewModelStores.of(fragment), factory);
}
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(ViewModelStores.of(activity), factory);
}
获取ViewModelStore:由前面的源码可以知道创建ViewProvider时传入两个参数:ViewModelStore 和 Factory;显然从名字就可以看出他们的作用,Factory负责创建,ViewModelStore负责存储
@NonNull
@MainThread
public T get(@NonNull String key, @NonNull Class modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
viewModel = mFactory.create(modelClass);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
上面的执行是,先去ViewModelStore中获取,如果为空就调用Factory的create()创建ViewModel,并储存在VIewmoStore中
ViewModelProviders.of(SquareFragment.this).get(AudioLiveData.class)的执行流程大概图 忽略创建和存储细节
2,通过ViewModelStores.of(this)创建ViewModelStore 源码
private ViewModelStores() {
}
@NonNull
@MainThread
public static ViewModelStore of(@NonNull FragmentActivity activity) {
if (activity instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) activity).getViewModelStore();
}
return holderFragmentFor(activity).getViewModelStore();
}
@NonNull
@MainThread
public static ViewModelStore of(@NonNull Fragment fragment) {
if (fragment instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) fragment).getViewModelStore();
}
return holderFragmentFor(fragment).getViewModelStore();
}
先判断Activity是否为 ViewModelStoreOwner,如果是直接获取其中的ViewModelStore,否则调用holderFragmentFor(activity).getViewModelStore()获取
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static HolderFragment holderFragmentFor(FragmentActivity activity) {
return sHolderFragmentManager.holderFragmentFor(activity);
}
...
HolderFragment holderFragmentFor(FragmentActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
//通过manager.findFragmentByTag(HOLDER_TAG)找到fragment
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedActivityHolders.get(activity);
//在map中取
if (holder != null) {
return holder;
}
if (!mActivityCallbacksIsAdded) {
mActivityCallbacksIsAdded = true;
activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
}
//创建 HolderFragment
holder = createHolderFragment(fm);
//存到map中
mNotCommittedActivityHolders.put(activity, holder);
return holder;
}
其中 findHolderFragment
private static HolderFragment findHolderFragment(FragmentManager manager) {
if (manager.isDestroyed()) {
throw new IllegalStateException("Can't access ViewModels from onDestroy");
}
Fragment fragmentByTag = manager.findFragmentByTag(HOLDER_TAG);
if (fragmentByTag != null && !(fragmentByTag instanceof HolderFragment)) {
throw new IllegalStateException("Unexpected "
+ "fragment instance was returned by HOLDER_TAG");
}
return (HolderFragment) fragmentByTag;
}
map中get
@SuppressWarnings("WeakerAccess")
static class HolderFragmentManager {
private Map mNotCommittedActivityHolders = new HashMap<>();
private Map mNotCommittedFragmentHolders = new HashMap<>();
...
holder = mNotCommittedActivityHolders.get(activity);
createHolderFragment
private static HolderFragment createHolderFragment(FragmentManager fragmentManager) {
HolderFragment holder = new HolderFragment();
fragmentManager.beginTransaction().add(holder, HOLDER_TAG).commitAllowingStateLoss();
return holder;
}
3, HolderFragment存储ViewModelStore
上面都是获取或者创建HolderFragment的过程,有没有想过我们存储ViewModel的地方,为什么一直在操作fragment ?我们回头看创建ViewModelStore的地方
有这么个判断 activity instanceof ViewModelStoreOwner
@NonNull
@MainThread
public static ViewModelStore of(@NonNull FragmentActivity activity) {
if (activity instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) activity).getViewModelStore();
}
return holderFragmentFor(activity).getViewModelStore();
}
...
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}
而HolderFragment实现了ViewModelStoreOwner,同时保存了ViewModelStore
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class HolderFragment extends Fragment implements ViewModelStoreOwner {
...
private ViewModelStore mViewModelStore = new ViewModelStore();
@NonNull
@Override
public ViewModelStore getViewModelStore() {
return mViewModelStore;
}
ViwModelStore 利用HashMap获取,存储 ViewModel
public class ViewModelStore {
private final HashMap mMap = new HashMap<>();
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) {
oldViewModel.onCleared();
}
}
final ViewModel get(String key) {
return mMap.get(key);
}
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.onCleared();
}
mMap.clear();
}
}
总结一下ViewModel内部的存储逻辑
LiveData 是一个观察者模型,但是它是一个与 Lifecycle 绑定了的 Subject,也就是说,只有当 UI 组件处于 ACTIVE 状态时,它的 Observer 才能收到消息,否则会自动切断订阅关系
public class SingleLiveEvent extends MutableLiveData {
private static final String TAG = "SingleLiveEvent";
private final AtomicBoolean mPending = new AtomicBoolean(false);
@MainThread
public void observe(LifecycleOwner owner, final Observer observer) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
}
// Observe the internal MutableLiveData
super.observe(owner, new Observer() {
@Override
public void onChanged(@Nullable T t) {
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t);
}
}
});
}
@MainThread
public void setValue(@Nullable T t) {
mPending.set(true);
super.setValue(t);
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
public void call() {
setValue(null);
}
}
汇总一下 LiveData 的使用场景:
LiveData转换
private class User{
private User(String id){ this.userId = id; }
private String userName;
private String userId;
}
private MutableLiveData userMutableLiveData;
public void test(){
userMutableLiveData = new MutableLiveData<>();
LiveData userName = Transformations.map(userMutableLiveData, new Function() {
@Override
public String apply(User input) {
return "姓名"+input.userName;
}
});
private class User{
private User(String id){ this.userId = id; }
private String userName;
private String userId;
}
private MutableLiveData userMutableLiveData;
public void test(){
userMutableLiveData = new MutableLiveData<>();
LiveData userId = new MutableLiveData<>();
LiveData user2 = Transformations.switchMap(userId, new Function>() {
@Override
public LiveData apply(String input) {
return getUser(input);
}
});
}
private LiveData getUser(String id){
User user = new User(id);
userMutableLiveData.setValue(user);
return userMutableLiveData;
}
MutableLiveData只是LiveData的一个扩展类,重写了LiveData中的protected方法postValue()和setValue(),调用了super.postValue()和super.setValue(),也就是说所有的方法都是在LiveData中实现
@SuppressWarnings("WeakerAccess")
public class MutableLiveData extends LiveData {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
先看 observe(@NonNull LifecycleOwner owner, @NonNull Observer observer)
flowerModel.getLiveData().observe(getActivity(), new Observer() {
@Override
public void onChanged(@Nullable FlowerModel.Data data) {
//update UI
}
});
...
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 如果已经销毁就返回
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);
}
private abstract class ObserverWrapper {
final Observer mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer observer) {
//保存观察者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();// 当Activity/Fragment为活跃状态时回调onActive()
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive(); // 当Activity/Fragment未活跃状态时回调onInactive()
}
if (mActive) {
dispatchingValue(this);
}
}
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
super(observer);// 调用父类ObserverWrapper的构造函数传递Owner
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// 实现GenericLifecycleObserver 当生命周期改变时回调onStateChanged
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);// DESTROYED时移除观察者
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
setValue(T value) (主线程)
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");//检测是否在主线程
mVersion++;
mData = value;
dispatchingValue(null);
}
...
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//遍历mObservers中所有的Observer,调用considerNotify()更新数据
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
...
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//更新数据 通过接口回调
observer.mObserver.onChanged((T) mData);
}
...
public interface Observer {
void onChanged(@Nullable T t);
}
...
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class DefaultTaskExecutor extends TaskExecutor {
private final Object mLock = new Object();
private ExecutorService mDiskIO = Executors.newFixedThreadPool(2);
@Nullable
private volatile Handler mMainHandler;
@Override
public void executeOnDiskIO(Runnable runnable) {
mDiskIO.execute(runnable);
}
@Override
public void postToMainThread(Runnable runnable) {
//子线程向主线程发消息
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
@Override
public boolean isMainThread() {//检测是否在主线程具体实现
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
...
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
本次分享只是分析了ViewModel,LiveData 的大概源码,与简单示例,但其实在实际生产环境中,我们需要使用ViewModel与Repository连接网络层,同时如果需要数据持久化还需要连接Room数据库层,通过ViewModel生成LiveData,UI层订阅LiveData,真正的实现**数据驱动界面**