引言
Lifecycle 是官方提供的架構組件之一,目前已經是穩定版本,Lifecycle 組件包括LifecycleOwner、LifecycleObserver。Lifecycle 組件是執行操作以響應另一個組件(Activity或者Fragment)的生命周期狀態的更改。 Lifecycle 生成更易於組織、更輕量級,更易於維護的代碼。
不使用Lifecycle
在使用MVP模式中,如果需要Presenter感知Activity或者Fragment的生命周期,傳統做法是Presenter中定義多個和Activity或者Fragment相應的生命周期方法,然后在Activity或者Fragment中調用Presenter中定義的方法,例如:
class UserPresenter(view: IUserView) {
private val mView = view
private val mModel: UserModel = UserModel()
fun onStart(){
// 初始化一些信息
}
fun onDestroy(){
// 釋放一起請求
}
}
class MainActivity : AppCompatActivity(), IUserView {
private val userPresenter = UserPresenter(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
override fun onStart() {
super.onStart()
userPresenter.onStart()
}
override fun onDestroy() {
super.onDestroy()
userPresenter.onDestroy()
}
override fun onLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onSuccess() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onComplete() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
實際項目中,需求可能比較復雜,這樣會導致太多類似的調用,而使onStart()和onDestroy() 方法變的非常臃腫。
使用Lifecycle
定義IPresenter 接口類,繼承LifecycleObserver ,其它具體的Presenter繼承該類,方便使用。
interface IPresenter : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart(owner: LifecycleOwner)
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(owner: LifecycleOwner)
}
定義一個具體的UserPresenter,繼承IPresenter
class UserPresenter(view: IUserView) : IPresenter {
private val mView = view
private val mModel: UserModel = UserModel()
companion object {
const val TAG: String = "UserPresenter"
}
override fun onStart(owner: LifecycleOwner) {
Log.d(TAG,"onStart and Presenter")
}
override fun onDestroy(owner: LifecycleOwner) {
Log.d(TAG,"onDestroy and Presenter")
}
}
在Activity或者Fragment使用
class MainActivity : AppCompatActivity(), IUserView {
companion object {
val TAG: String = "MainActivity"
}
private val userPresenter = UserPresenter(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
lifecycle.addObserver(userPresenter)// 訂閱事件
}
override fun onStart() {
super.onStart()
Log.d(TAG,"onStart and UI")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG,"onDestroy and UI")
}
override fun onLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onSuccess() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onComplete() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
運行查看下日志
2018-12-15 12:39:50.715 2679-2679/com.fomin.arch D/MainActivity: onStart and UI
2018-12-15 12:39:50.715 2679-2679/com.fomin.arch D/UserPresenter: onStart and Presenter
2018-12-15 12:39:53.876 2679-2679/com.fomin.arch D/UserPresenter: onDestroy and Presenter
2018-12-15 12:39:53.877 2679-2679/com.fomin.arch D/MainActivity: onDestroy and UI
這樣Presenter 感知Activity或Fragment的生命周期已經實現,在Activity或Fragment生命周期變化會及時通知到Presenter。無需再Activity或Fragment實現相關Presenter的生命周期感知事件,減少維護成本。
Lifecycle原理
首先了解下Lifecycle組件主要有下面一些關鍵類
- LifecycleObserver :實現該接口的類,通過注解的方式,可以通過被LifecycleOwner類的addObserver方法注冊,被注冊后,LifecycleObserver便可以觀察到LifecycleOwner的生命周期事件
- LifecycleOwner:實現該接口的類持有生命周期(Lifecycle對象),該接口的生命周期(Lifecycle對象)的改變會被其注冊的觀察者LifecycleObserver觀察到並觸發其對應的事件
- Event:從框架和Lifecycle類派發的生命周期事件
- State :由Lifecycle對象跟蹤的組件的當前狀態
- LifecycleRegistry:負責控制state的轉換、接受分發event事件
已Activity為例,會發現在SupportActivity里面繼承了LifecycleOwner,持有LifecycleRegistry類,並且在getLifecycle()返回LifecycleRegistry類,方便繼承類使用該類。
@RestrictTo(LIBRARY_GROUP)
public class SupportActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
@SuppressWarnings("RestrictedApi")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
@CallSuper
@Override
protected void onSaveInstanceState(Bundle outState) {
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
super.onSaveInstanceState(outState);
}
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
而在業務Activity中需要lifecycle.addObserver(LifecycleObserver)訂閱事件,這樣就可以生效訂閱/通知事件。Event分發是通過哪里進行分發的呢?可以看下ReportFragment.injectIfNeededIn(this)這句代碼,ReportFragment對各個狀態使用dispatch進行事件分發,然后調用LifecycleRegistry.handleLifecycleEvent,其接受到分發的Event從而改變State。
ReportFragment代碼片段
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
(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;
}
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);
}
}
}
LifecycleRegistry代碼片段
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
// happens only on the top of stack (never in reentrance),
// so it doesn't have to take in account parents
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
+ "new events from it.");
return;
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
可以看下官方的對整個生命周期流動的解釋
在該Lifecycle組件中,與傳統的生命周期不同,只定義了五種狀態,分別是:
- INITIALIZED 最初始的狀態
- DESTROYED
- CREATED
- STARTED
- RESUMED
上圖中向右的箭頭很好理解,每過來一個event會發生生命周期狀態的變更,向左的箭頭可以看成狀態的回滾, 如果在RESUMED狀態發生了ON_PAUSE事件,則狀態回滾到STARTED狀態;STARTED狀態發生了ON_STOP事件,則回滾到CREATED狀態。
總結
需要注意了是,在繼承LifecycleObserver 時,官方建議使用DefaultLifecycleObserver ,因為隨着Java8成為主流,將不會再使用注解方式,DefaultLifecycleObserver是需要另外聲明的java8,並且最低API24才能build success。而GenericLifecycleObserver,FullLifecycleObserver,DefaultLifecycleObserver 這三個接口都是直接或者間接繼承的LifecycleObserver。
// java8的lifecycle引用
implementation "android.arch.lifecycle:common-java8:1.1.1"
// 注解方式lifecycle引用
implementation 'android.arch.lifecycle:extensions:1.1.1'
Lifecycle使用,保持 UI 控制器(Activity 和 Fragment)盡可能的精簡,更易復用,同時和LiveData、ViewModel等使用更具有最佳實戰。