本篇文章主要讲解如何快速实现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()
}

这样,我们就可以在onCreateonDestory等方法中监听到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();
    ...
}

ActivityonStart中调用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,可以是ActivityFragment等等。

Glide添加SupportRequestManagerFragment的用意就是为了监听FragmentActivity的生命周期,当界面可见就去执行/恢复图片加载请求,界面不可见就停止图片加载的请求,界面销毁时执行资源释放的一些操作。

这个就是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 ResultAPI,具体使用可以看下郭神的文章。

添加:

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
        }
    }

源码很简单,原理和开头讲的一摸一样,大家看下即可。