概述
Android Architecture Components是一系列库集合,能帮助你设计出健壮的,可测试的,可维护的应用。使用几个类,来管理UI组件的生命周期和处理数据持久化。
-
管理app的生命周期很轻松。新的lifecycle-aware components组件,能帮助你管理activity/fragment的生命周期。保存配置更改,避免内存泄漏并轻松加载数据。
-
使用LiveData构建数据对象,在底层数据库更改时通知视图。
-
ViewModel存储UI相关数据,这些数据不会在应用旋转中被销毁。
-
Room是一个SQLite对象映射库。使用它避免样板代码,并容易地将SQLite表数据转换为Java对象。提供SQLite语句的编译时检查,并可以返回RxJava,Flowable和LiveData可观察对象。
架构图
推荐使用官方架构,模块的交互方式如下:
Picture生命周期感知组件
感知生命周期的组件执行动作,以响应其他组件(如Activity和Fragment)的生命周期状态的变化。这些组件有助于产生更好的组织性和更轻的重量代码,这更易于维护。
一种常见的模式是在Activity和Fragment的生命周期方法中实现依赖组件的动作。然而,这种模式导致代码的组织和错误扩散。通过使用生命周期感知组件,可以将依赖组件的代码从生命周期方法中移出并移入组件本身。
生命周期包提供了允许您构建生命周期感知组件的类和接口,这些组件可以根据Activity和Fragment的当前生命周期状态自动调整它们的行为。
Lifecycle-Aware Components,主要包含三个基本接口:
- LifecycleOwner
interface LifecycleOwner {
getLifecycle();
}
在FragmentActivity和Fragment实现,返回Lifecycle对象,用来给外部管理生命周期状态。
- Lifecycle
Lifecycle对象,能观察LifecycleObserver对象,并返回当前LifecycleOwner的生命周期状态(started,created)。
- LifecycleObserver
实现LifecycleObserver的类,能通过注解的方式,接收到状态变化的通知。如:
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate(LifecycleOwner lifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume(LifecycleOwner lifecycleOwner) {
}
比如,ViewModel类实现了LifecycleObserver接口,在Activity里添加getLifecycle().addObserver(viewModel);
那ViewModel就有了生命周期感知功能。
在Android框架中定义的大多数应用程序组件都有生命周期。生命周期是由操作系统或运行在您的进程中的框架代码管理的。它们是Android工作的核心,你的应用程序必须尊重它们。不这样做可能触发内存泄漏或甚至应用崩溃。
想象一下,我们有一个Activity显示屏幕上的设备位置。一个常见的实现方式可能如下:
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, location -> {
// update UI
});
}
@Override
public void onStart() {
super.onStart();
Util.checkUserStatus(result -> {
// what if this callback is invoked AFTER activity is stopped?
if (result) {
myLocationListener.start();
}
});
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
用了Lifecycle,还可以这样:
public class MyObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
是不是清晰很多。
LiveData
LiveData是一个可观测的数据保持类。与常规观察不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件(如Activity、Fragment或Service)的生命周期。这种感知确保LiveData只更新处于活跃生命周期状态的应用程序组件观察者。
您可以注册一个与实现 LifecycleOwner
接口的对象配对的观察者。这种关系允许当相应 ([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[%7C)60d8d77e15b1b69c7a3cfbc6b952b9393 |]对象的状态改变为([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[|) 60d8d77e15b1b69c7a3cfbc6b952b9394 |]时观察者被移除。这对于Activity和Fragment尤其有用,因为它们可以安全地观察 ([https://developer.android.google.cn/reference/android/arch/lifecycle/LiveData.html)|[%7C)60d8d77e15b1b69c7a3cfbc6b952b9395 |]对象,而不用担心泄漏——当Activity或Fragment的生命周期被销毁时,它们会立即取消订阅。
有关如何使用LiveData的更多信息,请参见使用LiveData对象。
使用LiveData的优势
-
确保UI与数据状态匹配
LiveData遵循观察者模式。当生命周期状态改变时,LiveData通知观察者对象。您可以合并代码来更新这些观察对象中的UI。每次应用程序数据更改时,都不更新UI,观察者可以每次更改时更新UI。 -
没有内存泄漏
观察者绑定到生命周期对象,并在其关联的生命周期被销毁后自行清理。 -
停止Activity时的崩溃
如果观察者的生命周期是不活动的,比如在后堆栈中的活动,那么它不接收任何LiveData事件。 -
无需手动处理生命周期
UI组件只是观察相关数据,不停止或恢复观察。LiveData自动管理所有这一切,因为它意识到相关的生命周期状态变化,同时观察。 -
始终保持最新数据
如果生命周期变得不活动,则在再次激活时接收最新数据。例如,后台中的Activity在返回到前台后立即接收最新数据。 -
正确的配置改变
如果由于配置改变而重新生成Activity或Fragment,例如设备旋转,则它立即接收最新可用数据。 -
资源共享
您可以使用Sigelon模式扩展LiveData对象来包装系统服务,以便它们可以在您的应用程序中共享。LiveData对象连接到系统服务一次,然后需要该资源的任何观察者都可以只观察LiveData对象。有关更多信息,请参见扩展LiveData。
如何使用LiveData
按照以下步骤使用LiveData对象:
-
创建一个LiveData实例来保存某种类型的数据。这通常是在ViewModel类中完成的。
-
创建一个Observer对象,该对象定义onChanged()方法,该方法控制LiveData对象保存的数据更改时发生的情况。通常在UI控制器,例如Activity或Fragment中,创建一个Observer对象。
-
使用
observe()
60d8d77e15b1b69c7a3cfbc6b952b93910 |]方法传入([https://developer.android.google.cn/reference/android/arch/lifecycle/LifecycleOwner.html)|[%7C)60d8d77e15b1b69c7a3cfbc6b952b93911 |]对象。这将观察对象向LiveData对象订阅,以便通知其更改。通常将观察者对象附加在UI控制器中,例如Activity或Fragment。 -
当更新LiveData对象中存储的值时,只要所附的LifecycleOwner处于活动状态,就会触发所有已注册的观察器。
LiveData允许UI控制器观察员订阅更新。当LiveData对象保存的数据发生变化时,UI会自动响应更新。
创建LiveData
public class NameViewModel extends ViewModel {
// Create a LiveData with a String
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<String>();
}
return mCurrentName;
}
// Rest of the ViewModel...
}
观察LiveData
public class NameActivity extends AppCompatActivity {
private NameViewModel mModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Other code to setup the activity...
// Get the ViewModel.
mModel = ViewModelProviders.of(this).get(NameViewModel.class);
// Create the observer which updates the UI.
final Observer<String> nameObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI, in this case, a TextView.
mNameTextView.setText(newName);
}
};
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
mModel.getCurrentName().observe(this, nameObserver);
}
}
扩展LiveData
LiveData认为观察者必须在有效状态,无论是在STARTED
或([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#RESUMED)|[|) 60d8d77e15b1b69c7a3cfbc6b952b93914 |]状态,可以用来做全局数据共享,
下面的示例代码说明如何扩展LiveData类:
public class StockLiveData extends LiveData<BigDecimal> {
private StockManager mStockManager;
private SimplePriceListener mListener = new SimplePriceListener() {
@Override
public void onPriceChanged(BigDecimal price) {
setValue(price);
}
};
public StockLiveData(String symbol) {
mStockManager = new StockManager(symbol);
}
@Override
protected void onActive() {
mStockManager.requestPriceUpdates(mListener);
}
@Override
protected void onInactive() {
mStockManager.removeUpdates(mListener);
}
}
多种场景下的使用
Activity/Fragment
最基本的UI场景,只需要在Activity/Fragment调用observe()方法关注LiveData数据,即可。
需要注意的是,使用Activity/Fragment都是LifecycleOwner对象,需要哪个LifecycleOwner就看业务需要。
ViewHolder
比如在RecyclerView的ViewHolder里面观察LiveData,因为ViewHolder有缓存机制,所以Observer跟item并不一对一。一般可以在初始化ViewHolder时,观察LiveData,然后接收到数据变更,则修改item数据,并重修刷新ui。这样才能做到兼容ViewHolder机制。
View/ViewGroup
如果View不涉及到销毁(重建)的情况,也不需要理会Observer,否则,也要管理Observer的观察和取消观察。
UI组件以外
UI组件以外,需要用到observeForever()方法,此方法没有生命周期感知,需要手动管理取消观察。
ViewModel管理LiveData和全局LiveData的区别
本质上没有不同,主要在于数据本身生命周期的需要和共享的需要。
比如ViewModel的LiveData会随着Activity/Fragment产生、共享和销毁,而全局的LiveData是跟随进程或手动管理的。
LiveData的创建场景和观察场景
LiveData能在任何地方,任何情况创建。
观察场景可以在UI组件使用observe()/observeForever()方法,或其他非UI场景只能用observeForever()方法。
附言
以上为个人的经验总结,不当之处欢迎讨论,并持续优化。
网友评论