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中的一些膠水代碼,也能很好的剝離出來,避免因無法感知到生命週期存在的內存泄露問題。
引入Lifecycle
這裏我們使用android X引入方式
api 'androidx.appcompat:appcompat:1.1.0'
appcompat默認已經內置lifecycle-common組件,我們無需單獨引用了。
如需要指定java8可添加如下引用
api 'androidx.lifecycle:lifecycle-common-java8:2.1.0'
Support版本的引入方式
注: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) {
}
}
在Activity/Frament中進行綁定
綁定
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;
}
}
如何利用好lifecycle
愈演愈烈的MVP、MVVM開發模式中,我們會將Activity/Fragment中的原有代碼邏輯拆散到各個模塊中,好處是各自模塊負責管理自己的職責,但缺點對生命週期感知幾乎是沒有,這樣就會有導致有很多膠水代碼,每個模塊邏輯就像是補丁一樣和原始頁面緊緊關聯在一起。
以MVP開發模式爲例,我們如何增強生命週期感知能力呢.
利用剛剛封裝好的LifecycleBindHelper,我們針對Presenter封裝一層BasePresenter。
使用案例1:登錄模塊
代碼如下:
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處理生命週期問題了
使用案例2:播放器場景
在沒有使用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來通知所有的觀察者,所以我們在外部就可以輕鬆的感知到生命週期了。
最後LifecycleObserver、Lifecycle、LifecycleRegistry、ComponentActivity、
ReportFragment之間的關聯可以總結爲如下圖。
注:關於Jetpack AAC架構組件系列後續還會分析詳解,可以關注公衆號,早上八點不定時更新。