原文链接
Android Jetpack是2018年谷歌I/O发布的一系列辅助android开发者的实用工具,合称Jetpack,以帮助开发者构建出色的 Android 应用。Android Jetpack 组件覆盖以下 4 个方面:Architecture、Foundation、Behavior 以及 UI。
Lifecycle则是Architecture Compinents官方架构组件之一。Lifecycle的推出让开发者能够在非Fragment和activity中也能感知到fragment和activity生命周期, 开发者也能更专注于处理逻辑的本身,而很多嵌套在Activity/Fragment中的一些胶水代码,也能很好的剥离出来,避免因无法感知到生命周期存在的内存泄露问题。
这里我们使用android X引入方式
api 'androidx.appcompat:appcompat:1.1.0' 复制代码
appcompat默认已经内置lifecycle-common组件,我们无需单独引用了。
如需要指定java8可添加如下引用
api 'androidx.lifecycle:lifecycle-common-java8:2.1.0' 复制代码
注:support版本默认也有引入lifecycle,这里添加一个注解编译即可
implementation "com.android.support:appcompat-v7:28.0.0" annotationProcessor "android.arch.lifecycle:compiler:1.1.1" //java8使用引入 implementation "android.arch.lifecycle:common-java8:1.1.1" 复制代码
java7中的用法
public interface LifecycleObserverIml extends LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.On_CREATE) void onCreate(); @OnLifecycleEvent(Lifecycle.Event.ON_START) void onStart(); @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) void onResume(); @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) void onPause(); @OnLifecycleEvent(Lifecycle.Event.ON_STOP) void onStop(); @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) void onDestroy(); } 复制代码
java8中的用法
public interface LifecycleObserverIml8 extends DefaultLifecycleObserver { @Override default void onCreate(@NonNull LifecycleOwner owner) { } @Override default void onStart(@NonNull LifecycleOwner owner) { } @Override default void onResume(@NonNull LifecycleOwner owner) { } @Override default void onPause(@NonNull LifecycleOwner owner) { } @Override default void onStop(@NonNull LifecycleOwner owner) { } @Override default void onDestroy(@NonNull LifecycleOwner owner) { } } 复制代码
绑定
getLifecycle().addObserver(lifecycleObserver); 复制代码
解绑
getLifecycle().removeObserver(lifecycleObserver) 复制代码
使用上是不是既简单又实用呢?那么问题就来了,如果我既要在Fragment中使用也要在Activity中使用,能不能像Glide一样,传进来的是什么级别上下文,内部自动绑定对应的上下文级别的生命周期呢?
答案是肯定的!我们来手撸一个绑定的辅助类
public class LifecycleBindHelper { private LifecycleOwner lifecycleOwner; // 生命周期回调 private ArrayMap<Object, LifecycleObserver> lifecyleCallbacks = new ArrayMap<>(); public static LifecycleBindHelper with(Object object) { return new LifecycleBindHelper(object); } public static LifecycleBindHelper with(AppCompatActivity object) { return new LifecycleBindHelper(object); } public static LifecycleBindHelper with(Fragment object) { return new LifecycleBindHelper(object); } private AppLifecycleBindHelper(Object object) { if (object != null && object instanceof LifecycleOwner) { lifecycleOwner = (LifecycleOwner) object; } } public LifecycleBindHelper addLifecyleCallback(LifecycleObserver lifecycleObserver) { if (hasRefrence() && lifecycleObserver != null) { lifecyleCallbacks.put(lifecycleObserver, lifecycleObserver); lifecycleOwner.getLifecycle().addObserver(lifecycleObserver); } return this; } public LifecycleBindHelper removeLifecyleCallback(LifecycleObserver lifecycleObserver) { if (hasRefrence() && lifecycleObserver != null) { lifecyleCallbacks.remove(lifecycleObserver); this.lifecycleOwner.getLifecycle().removeObserver(lifecycleObserver); } return this; } private LifecycleObserver[] getLifecycleCallbacks() { LifecycleObserver[] callbacks = new LifecycleObserver[lifecyleCallbacks.values().size()]; lifecyleCallbacks.values().toArray(callbacks); return callbacks; } public boolean hasRefrence() { return null != this.lifecycleOwner; } /** * 清除所有的回调(只能清除当前对象添加的回调,其他方式添加的回调监听可以通过手动移除形式) */ public void clearAll() { if (!hasRefrence()) { return; } for (LifecycleObserver lifecycleObserver : getLifecycleCallbacks()) { removeLifecyleCallback(lifecycleObserver); } build(); } /** * 构建完成,不需要进行使用时调用 */ public void build() { lifecyleCallbacks.clear(); this.lifecycleOwner = null; } } 复制代码
愈演愈烈的MVP、MVVM开发模式中,我们会将Activity/Fragment中的原有代码逻辑拆散到各个模块中,好处是各自模块负责管理自己的职责,但缺点对生命周期感知几乎是没有,这样就会有导致有很多胶水代码,每个模块逻辑就像是补丁一样和原始页面紧紧关联在一起。
以MVP开发模式为例,我们如何增强生命周期感知能力呢. 利用刚刚封装好的LifecycleBindHelper,我们针对Presenter封装一层BasePresenter。
代码如下:
class BasePresenter implements LifecycleObserverIml { private LifecycleBindHelper lifecycleBindHelper; private static final String TAG = "BasePresenter"; private FragmentActivity mActivity; private Fragment mFragment; public BasePresenter(FragmentActivity context) { bindLifecycleOwner(context); } public BasePresenter(Fragment fragment) { bindLifecycleOwner(fragment); } private void bindLifecycleOwner(Object lifecycleOwner) { if (lifecycleBindHelper != null && lifecycleBindHelper.hasReference()) { lifecycleBindHelper.clearAll(); } if (lifecycleOwner instanceof FragmentActivity) { this.mActivity = (FragmentActivity) lifecycleOwner; } if (lifecycleOwner instanceof Fragment) { this.mFragment = (Fragment) lifecycleOwner; this.mActivity = this.mFragment.getActivity(); } lifecycleBindHelper = LifecycleBindHelper.with(lifecycleOwner). addLifecycleCallback(this); } public FragmentActivity getActivity() { return mActivity; } @Override public void onStart() { Log.e(TAG, "onStart: "); } @Override public void onResume() { Log.e(TAG, "onResume: "); } @Override public void onPause() { Log.e(TAG, "onPause: "); } @Override public void onStop() { Log.e(TAG, "onStop: "); } @Override public void onDestroy() { Log.e(TAG, "onDestroy: "); if (lifecycleBindHelper.hasReference()) { lifecycleBindHelper.clearAll(); } } } 复制代码
这样我们就能很好在Presenter处理生命周期问题了
在没有使用lifecycle时,我们通常是这样使用的
public class MainPlayerActivity extends AppCompatActivity { MediaPlayer mediaPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initPlayer(); } public void initPlayer() { mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/demo.mp4"); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } @Override protected void onResume() { super.onResume(); mediaPlayer.start(); } @Override protected void onPause() { super.onPause(); mediaPlayer.pause(); } @Override protected void onDestroy() { super.onDestroy(); mediaPlayer.stop(); } } 复制代码
当Activity中的生命周期变更后,我们也要同步去变更播放器的状态,看到这里,可能会说这没啥问题呀!设想一下,假设我们有2个甚至更多页面是否都得这样处理一遍呢?
我们来看看使用了lifycycle之后怎样处理的
public class MainPlayerNewActivity extends AppCompatActivity { PlayerManager playerManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initPlayer(); } public void initPlayer() { playerManager = new PlayerManager(this); playerManager.setDataSource( Environment.getExternalStorageDirectory() + "/demo.mp4"); } } 复制代码
public class PlayerManager extends BasePresenter { MediaPlayer mediaPlayer; public PlayerManager(FragmentActivity context) { super(context); mediaPlayer = new MediaPlayer(); } public void setDataSource(String path) { try { mediaPlayer.setDataSource(path); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onResume() { super.onResume(); mediaPlayer.start(); } @Override public void onPause() { super.onPause(); mediaPlayer.pause(); } @Override public void onDestroy() { super.onDestroy(); mediaPlayer.stop(); } } 复制代码
可以发现Activity中的代码是不是少了很多,并且PlayerManager就可以在各个页面进行复用了,并且在外部使用时,也不用关心生命周期变更的问题了。
源码分析以Android X为基础
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner, OnBackPressedDispatcherOwner { static final class NonConfigurationInstances { Object custom; ViewModelStore viewModelStore; } private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } } 复制代码
从上述代码我们可以看到我们在外部调用getLifecycle(),实际上获取的是LifecycleRegistry类对象。
public class LifecycleRegistry extends Lifecycle { //省略相关代码..... } 复制代码
LifecycleRegistry实现了Lifecycle接口,提供了增加/删除的观察者接口函数
public abstract class Lifecycle { @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @NonNull AtomicReference<Object> mInternalScopeRef = new AtomicReference<>(); @MainThread public abstract void addObserver(@NonNull LifecycleObserver observer); @MainThread public abstract void removeObserver(@NonNull LifecycleObserver observer); @MainThread @NonNull public abstract State getCurrentState(); } 复制代码
public class LifecycleRegistry extends Lifecycle { //省略相关代码..... 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) { throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already" + "garbage collected. It is too late to change lifecycle state."); } 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; } //省略相关代码..... } 复制代码
通过源码我们可以发现,所有的观察者所接受的事件都是由**handleLifecycleEvent(@NonNull Lifecycle.Event event)**函数来驱动,最后分发到forwardPass和backwardPass这两个函数来进行分发和同步的操作。
forwardPass() 遍历观察者集合,当观察者生命周期状态小于当前生命周期状态时 分发事件
private void forwardPass(LifecycleOwner lifecycleOwner) { Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator = mObserverMap.iteratorWithAdditions(); while (ascendingIterator.hasNext() && !mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue(); while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { pushParentState(observer.mState); observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); } } } 复制代码
backwardPass() 遍历观察者集合,当观察者生命周期状态大于当前生命周期状态时 分发事件
private void backwardPass(LifecycleOwner lifecycleOwner) { Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator = mObserverMap.descendingIterator(); while (descendingIterator.hasNext() && !mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next(); ObserverWithState observer = entry.getValue(); while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { Event event = downEvent(observer.mState); pushParentState(getStateAfter(event)); observer.dispatchEvent(lifecycleOwner, event); popParentState(); } } } 复制代码
那么问题就来了,在哪发起调用 handleLifecycleEvent() 函数呢?我们查看ComponentActivity源码似乎只对外提供了一个getLifecycle函数
一番查找后在ComponentActivity中的onCreate函数发现这行代码
public class ComponentActivity extends Activity implements LifecycleOwner, KeyEventDispatcher.Component { @SuppressLint("RestrictedApi") @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); } } 复制代码
把ReportFragment添加到了ComponentActivity中
public class ReportFragment extends Fragment { private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle" + ".LifecycleDispatcher.report_fragment_tag"; public static void injectIfNeededIn(Activity activity) { fragments for activities android.app.FragmentManager manager = activity.getFragmentManager(); if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) { manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit(); // Hopefully, we are the first to make a transaction. manager.executePendingTransactions(); } } } 复制代码
这时往下看ReportFragment中的代码,顿时就一目了然了
public class ReportFragment extends Fragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); dispatchCreate(mProcessListener); dispatch(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作为Lifecycle的实现类,职责是管理我们所添加的观察者,并存放至观察者集合中,ReportFragment作为生命周期代理的存在,当生命周期发生变更时,会通知和同步给LifecycleRegistry,最后由LifecycleRegistry来通知所有的观察者。所以我们在外部通过获取LifecycleRegistry注册就实现LifecycleObserver的观察者,就能轻松的感知到生命周期的变更了。
最后LifecycleObserver、Lifecycle、LifecycleRegistry、ComponentActivity、 ReportFragment之间的关联可以总结为如下图。
注:关于Jetpack AAC架构组件系列后续还会分析详解,可以关注公众号,早上八点不定时更新。