本篇文章主要讲解如何快速实现Activity生命周期监听,以及其在官方lifecycle、第三方库Glide、PermissionX中的应用
1.Activity
生命周期监听
-
Fragment
实现Activity
生命周期监听
众所周知,Fragment
中生命周期分发主要是依赖Activity
,所以为了监听Activity
的生命周期我们直接添加一个空的Fragment
即可:
class TestFragment(): Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onDestroy() {
super.onDestroy()
}
}
//首先要获取activity
activity.supportFragmentManager.beginTransaction().apply {
add(TestFragment(), "TestFragment").commit()
}
这样,我们就可以在onCreate
、onDestory
等方法中监听到Activity
的生命周期,执行相关逻辑即可
PS: 通过FragmentManager的FragmentTransaction添加Fragment时,add方法的第二个参数tag不要直接传入TestFragment::class.java.simpleName,因为一旦Fragment发生了混淆,可能会出现多个添加的不同Fragment的tag相同的情况,影响后续使用
-
registerActivityLifecycleCallbacks
实现Activity
生命周期监听(api>=29)
该方法主要是SDK>=29才提供的,看下源码:
//回调集合
private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<Application.ActivityLifecycleCallbacks>();
//添加监听Activity生命周期的回调
public void registerActivityLifecycleCallbacks(
@NonNull Application.ActivityLifecycleCallbacks callback) {
synchronized (mActivityLifecycleCallbacks) {
mActivityLifecycleCallbacks.add(callback);
}
}
看下mActivityLifecycleCallbacks
在哪里调用,这边就以Activity的onStart
生命周期举例:
private Object[] collectActivityLifecycleCallbacks() {
Object[] callbacks = null;
synchronized (mActivityLifecycleCallbacks) {
if (mActivityLifecycleCallbacks.size() > 0) {
callbacks = mActivityLifecycleCallbacks.toArray();
}
}
return callbacks;
}
private void dispatchActivityStarted() {
getApplication().dispatchActivityStarted(this);
//获取mActivityLifecycleCallback回调数组
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
//分发start生命周期
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityStarted(this);
}
}
}
protected void onStart() {
...
//调用dispatchActivityStarted实现生命周期分发
dispatchActivityStarted();
...
}
在Activity
的onStart
中调用dispatchActivityStarted()
方法分发生命周期,后者首先调用了collectActivityLifecycleCallbacks()
获取添加的生命周期回调集合并转换成数组,然后依次进行遍历分发Activity的onStart
生命周期
2.案例1:官方库lifecycle应用实践
官方库lifecycle
也是通过上面两种方式组合实现Activity
的生命周期监听:
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
LifecycleCallbacks.registerIn(activity);
}
//兼容旧版本
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
static void registerIn(Activity activity) {
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
从源码中可以看到,SDK>=29就使用registerActivityLifecycleCallbacks
监听生命周期,小于29就通过添加ReportFragment
到Activity的方式监听。
可以注意到即使sdk>=29也还是会走添加ReportFragment
的逻辑,这个主要是为了兼容旧版本
3.案例2:Glide库应用实践
Glide定义一个名为SupportRequestManagerFragment
,继承自Fragment
:
public class SupportRequestManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
@Override
public void onStart() {
lifecycle.onStart();
}
@Override
public void onStop() {
lifecycle.onStop();
}
@Override
public void onDestroy() {
lifecycle.onDestroy();
}
}
通过getSupportRequestManagerFragment()
添加到Activity
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = new SupportRequestManagerFragment();
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
}
}
return current;
}
大家都知道,使用Glide的with
函数需要传入一个Context
,可以是Activity
、Fragment
等等。
Glide添加SupportRequestManagerFragment
的用意就是为了监听Fragment
或Activity
的生命周期,当界面可见
就去执行/恢复图片加载请求,界面不可见
就停止图片加载的请求,界面销毁
时执行资源释放的一些操作。
这个就是Glide关于图片加载其中的一种优化措施,减少资源浪费
4.案例3:PermissionX库应用实践
这个库是实现权限申请的,权限申请肯定也是离不开Activity
的,为了尽可能不入侵业务层的逻辑,这里巧妙的使用了添加Fragment
的方式实现权限的申请以及回调处理:
class InvisibleFragment : Fragment() {
private val requestWriteSettingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
//权限申请回调处理
onRequestWriteSettingsPermissionResult()
}
//发起权限申请
fun requestWriteSettingsPermissionNow(permissionBuilder: PermissionBuilder, chainTask: ChainTask) {
requestWriteSettingsLauncher.launch(intent)
}
}
上面权限申请的写法是使用了Activity Result
API,具体使用可以看下郭神的文章。
添加:
private val invisibleFragment: InvisibleFragment
get() {
val existedFragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG)
return if (existedFragment != null) {
existedFragment as InvisibleFragment
} else {
val invisibleFragment = InvisibleFragment()
fragmentManager.beginTransaction()
.add(invisibleFragment, FRAGMENT_TAG)
.commitNowAllowingStateLoss()
invisibleFragment
}
}
源码很简单,原理和开头讲的一摸一样,大家看下即可。