LiveData 是一个 observable 数据的持有类,和普通的 observable 不同,LiveData 是生命周期感知的,意味着它代表其它应用组件譬如 Activity、Fragment、Service 的生命周期。
这确保了 LiveData 只会更新处于活跃状态的组件。
LiveData 通过内部类的形式实现了 LifecycleObserver,它整个工作流程大概是这样的:
1.将实现了 LifecycleObserver 的内部类注册到 owner 的 Lifecycle。
2.LifecycleObserver 监听了 Lifecycle 所有的生命周期事件
3.当有生命周期事件发生时,检查 Lifecycle 的状态是否至少是 STARTED 来判断 lifecycle 是否处于活跃状态
4.当维护的值被改变时,如果 Lifecycle 处于活跃状态,通知观察者(实现了 android.arch.lifecycle.Observer 接口的对象),否则什么也不做
5.当 Lifecycle 从非活跃状态恢复到活跃状态时,检查维护的值是否在非活跃期间有更新过,如果有,通知观察者
6.当 Lifecycle 处于完结状态 DESTROYED 时,从 Lifecycle 中移除 LifecycleObserver
LiveData的优势
1.没有内存泄漏:因为 Observer 被绑定到它们自己的 Lifecycle 对象上,所以,当它们的 Lifecycle 被销毁时,它们能自动的被清理
2.不会因为 activity 停止而崩溃:如果 Observer 的 Lifecycle 处于闲置状态(例如:activity 在后台时),它们不会收到变更事件
3.始终保持数据最新:如果 Lifecycle 重新启动(例如:activity 从后台返回到启动状态)将会收到最新的位置数据(除非还没有)
4.正确处理配置更改:如果 activity 或 fragment 由于配置更改(如:设备旋转)重新创建,将会立即收到最新的有效位置数据
5.资源共享:可以只保留一个 MyLocationListener 实例,只连接系统服务一次,并且能够正确的支持应用程序中的所有观察者
6.不再手动管理生命周期你可能已经注意到,fragment 只是在需要的时候观察数据,不用担心被停止或者在停止之后启动观察。由于 fragment 在观察数据时提供了其 Lifecycle,所以 LiveData 会自动管理这一切
Use LiveData
1.Create LiveData Objects
LiveData是一个泛型包装类,包含实现Collections接口的对象,例如List, ViewModel通常持有LiveData对象并且提供一个get方法获取LiveData, 通常LiveData不需要set
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...
}
2.Observe LiveData objects
大多数情况下,一个app组件的onCreate方法,是开始observing LiveData的地方
1) 确保系统没有从Activity或者Fragment的onResume方法的多余调用
2) 确保当Activity或者Fragment变成活跃状态的时候 能尽快展示数据,只要app的组件进入STARTED状态,从LiveData对象中接收观察到的最新的值
通常,当数据发生变化的时候,LiveData发送更新通知给活跃的观察者。唯一的异常行为是当观察者收到更新的时候,它的状态从inactive状态变成了active状态。并且,如果这个观察者再一次从inactive变成active,它仅仅
接收最后一次变成active的数据
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);
}
}
3.Update LiveData objects
LiveData并没有公共的可以更新存贮的数据的方法,MutableLivedData暴露setValue和postValue方法
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String anotherName = "John Doe";
mModel.getCurrentName().setValue(anotherName);
}
});
Extend LiveData
1.LiveData认为,一个Observer的生命周期状态是STARTED或者RESUMED的时候,就是一个active状态。举例说明怎样继承一个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);
}
}
onActive() 当LiveData持有一个active observer的时候 这个方法被调用
onInactive() 当LiveData不持有任何active observer的时候 这个方法被调用。
setValue() 更新数据的时候 调用
举例说明怎样使用StockLiveData
public class MyFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LiveData<BigDecimal> myPriceListener = ...;
myPriceListener.observe(this, price -> {
// Update the UI.
});
}
}
请注意,addObserver() 方法将 LifecycleOwner 作为第一个参数传递。这样做表示该观察者应该绑定到 Lifecycle,意思是:
如果 Lifecycle 不处于活动状态(STARTED 或 RESUMED),即使该值发生变化也不会调用观察者。
如果 Lifecycle 被销毁,那么自动移除观察者。
LiveData 是生命周期感知的事实给我们提供了一个新的可能:可以在多个 activity,fragment 等之间共享它。为了保持实例简单,可以将其作为单例
public class StockLiveData extends LiveData<BigDecimal> {
private static StockLiveData sInstance;
private StockManager mStockManager;
private SimplePriceListener mListener = new SimplePriceListener() {
@Override
public void onPriceChanged(BigDecimal price) {
setValue(price);
}
};
@MainThread
public static StockLiveData get(String symbol) {
if (sInstance == null) {
sInstance = new StockLiveData(symbol);
}
return sInstance;
}
private StockLiveData(String symbol) {
mStockManager = new StockManager(symbol);
}
@Override
protected void onActive() {
mStockManager.requestPriceUpdates(mListener);
}
@Override
protected void onInactive() {
mStockManager.removeUpdates(mListener);
}
}
调用方式:
public class MyFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
StockLiveData.get(getActivity()).observe(this, price -> {
// Update the UI.
});
}
}
ViewModel
ViewModel是用来存储UI层的数据,以及管理对应的数据,当数据修改的时候,可以马上刷新UI。
Android系统提供控件,比如Activity和Fragment,这些控件都是具有生命周期方法,这些生命周期方法被系统调用。
当这些控件被销毁或者被重建的时候,如果数据保存在这些对象中,那么数据就会丢失。比如在一个界面,保存了一些用户信息,当界面重新创建的时候,就需要重新去获取数据。
当然了也可以使用控件自动再带的方法,在onSaveInstanceState方法中保存数据,在onCreate中重新获得数据,但这仅仅在数据量比较小的情况下。如果数据量很大,这种方法就不能适用了。
另外一个问题就是,经常需要在Activity中加载数据,这些数据可能是异步的,因为获取数据需要花费很长的时间。
那么Activity就需要管理这些数据调用,否则很有可能会产生内存泄露问题。最后需要做很多额外的操作,来保证程序的正常运行。
同时Activity不仅仅只是用来加载数据的,还要加载其他资源,做其他的操作,最后Activity类变大,就是我们常讲的上帝类。
也有不少架构是把一些操作放到单独的类中,比如MVP就是这样,创建相同类似于生命周期的函数做代理,这样可以减少Activity的代码量,但是这样就会变得很复杂,同时也难以测试。
AAC中提供ViewModel可以很方便的用来管理数据。我们可以利用它来管理UI组件与数据的绑定关系。ViewModel提供自动绑定的形式,当数据源有更新的时候,可以自动立即的更新UI
CoordinatorLayout 协调布局 ConstraintLayout 约束布局
Service
网址:https://www.jianshu.com/p/d870f99b675c
网址:https://blog.csdn.net/veryitman/article/details/7600008
Service的onCreate、onStartCommand、onDestory等全部生命周期方法都运行在UI线程,ServiceConnection里面的回调方法也是运行在UI线程
1、startService开启服务以后,与activity就没有关联,不受影响,独立运行。
2、bindService开启服务以后,与activity存在关联,退出activity时必须调用unbindService方法,否则会报ServiceConnection泄漏的错误。
最后还有一点,同一个服务可以用两种方式一同开启,没有先后顺序的要求,MyService的onCreate只会执行一次。
关闭服务需要stopService和unbindService都被调用,也没有先后顺序的影响,MyService的onDestroy也只执行一次。但是如果只用一种方式关闭服务,不论是哪种关闭方式,onDestroy都不会被执行,服务也不会被关闭。这一点需要注意