赞
踩
Jetpack-activity/fragment 是jetpack架构组件中最基础的部分。
底层对jetpack-lifecycle组件做了支持、为开发者能够直接使用jetpack架构组件提供了支持,因此要想彻底了解jetpack系列,先学习activity/fragment组件很有必要。
注意:
本文中源代码均使用 1.1.0稳定版本
引用
def activity_version = "1.1.0"
// Java language implementation
implementation "androidx.activity:activity:$activity_version"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"
继承结构:
/** * Base class for activities that enables composition of higher level components. * <p> * Rather than all functionality being built directly into this class, only the minimal set of * lower level building blocks are included. Higher level components can then be used as needed * without enforcing a deep Activity class hierarchy or strong coupling between components. */ public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner, ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner, OnBackPressedDispatcherOwner { //.... }
从 ComponentActivity
类的注释上可以得出两条信息:
ComponentActivity
是一个支持组合高级组件的基类ActivityComponentActivity
在构造器中针对Android不同版本进行了简单兼容处理
public ComponentActivity() { Lifecycle lifecycle = getLifecycle(); //noinspection ConstantConditions //如果在使用 Lifecycle 对象的时候还没有初始化则直接抛错,对于重写 getLifecycle() 方法需要注意 if (lifecycle == null) { throw new IllegalStateException("getLifecycle() returned null in ComponentActivity's " + "constructor. Please make sure you are lazily constructing your Lifecycle " + "in the first call to getLifecycle() rather than relying on field " + "initialization."); } //针对API 19以上兼容 if (Build.VERSION.SDK_INT >= 19) { getLifecycle().addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event == Lifecycle.Event.ON_STOP) { Window window = getWindow(); final View decor = window != null ? window.peekDecorView() : null; if (decor != null) { decor.cancelPendingInputEvents(); } } } }); } //Activity销毁时清除ViewMode中数据 getLifecycle().addObserver(new LifecycleEventObserver() { @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event == Lifecycle.Event.ON_DESTROY) { if (!isChangingConfigurations()) { getViewModelStore().clear(); } } } }); //针对 19~23 版本 解决 InputMethodManager中 mNextServedView 内存泄漏问题 if (19 <= SDK_INT && SDK_INT <= 23) { getLifecycle().addObserver(new ImmLeaksCleaner(this)); } }
从构造器中代码来看做的事情比较多,但都是兼容性处理,有三个方面的处理:
在 Activity
处于stop 时用户是看不到界面的,也没有必要再处理 View
的点击、长按、动画等事件。所以有必要将这些事件移除掉。
我们跟随源码看一下具体是怎么做的:
上述代码会调用View
中 cancelPendingInputEvents()
这是个取消事件的总调度方法,它没有具体做事情,而是调用了 dispatchCancelPendingInputEvents()
来完成工作
public final void cancelPendingInputEvents() { dispatchCancelPendingInputEvents(); } void dispatchCancelPendingInputEvents() { //位操作设置标志位 mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER; //执行清除事件工作 onCancelPendingInputEvents(); //检查标志位是否正确 以确保完成了清除工作 if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) { throw new SuperNotCalledException("View " + getClass().getSimpleName() + " did not call through to super.onCancelPendingInputEvents()"); } }
在 dispatchCancelPendingInputEvents()
方法中调用了 onCancelPendingInputEvents()
来完成具体的清除工作:
onCancelPendingInputEvents()
会清除已发送到消息队列的事件,延迟事件等 如果是自定义View
是可以重写此方法,来自定义指定那些事件是需要清除或保留的,但是需要注意要 super.onCancelPendingInputEvents()
要调用父类方法 完成 mPrivateFlags3变量的位操作
public void onCancelPendingInputEvents() {
//移除点击事件回调
removePerformClickCallback();
//取消等待的长按事件
cancelLongPress();
//对标识变量进行操作 在 dispatchCancelPendingInputEvents()对此变量有检查操作
mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
}
在 removePerformClickCallback()
中直接调用 removeCallbacks
将 mPerformClick
点击事件传入
@UnsupportedAppUsage
private void removePerformClickCallback() {
if (mPerformClick != null) {
removeCallbacks(mPerformClick);
}
}
removeCallbacks(Runnable action)
才是真正移除事件处理的方法,凡是以下几种方式添加的事件或延迟事件都会移除
post()
postDelayed()
postOnAnimation()
postOnAnimationDelayed()
public boolean removeCallbacks(Runnable action) { if (action != null) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { //移除指定回调 attachInfo.mHandler.removeCallbacks(action); //移除Choreographer中动画回调 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks( Choreographer.CALLBACK_ANIMATION, action, null); } //移除等待队列中事件 getRunQueue().removeCallbacks(action); } return true; }
在 cancelLongPress()
中会分别调用 removeLongPressCallback()
清除长按回调 和 removeTapCallback()
移除长按产生的超时事件
removeLongPressCallback()
和 removeTapCallback()
都会调用 removeCallbacks(Runnable action)
来移除指定的事件,前面我们已经分析过了,就不再赘述了。
public void cancelLongPress() { //移除长按回调事件 removeLongPressCallback(); //移除长按超时回调事件 removeTapCallback(); } //移除长按回调 private void removeLongPressCallback() { if (mPendingCheckForLongPress != null) { removeCallbacks(mPendingCheckForLongPress); } } //移除长按超时事件、修改标志位 private void removeTapCallback() { if (mPendingCheckForTap != null) { mPrivateFlags &= ~PFLAG_PREPRESSED; removeCallbacks(mPendingCheckForTap); } }
Activity
销毁时清除ViewMode
中数据,需要依赖另一个组件-Lifecycle
支持。不仅是 ViewModel
在Jetpack 架构组件中很多组件都需要依赖 Lifecycle
组件。
我们重新看一下以下代码
//Activity销毁时清除ViewMode中数据
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。