监听Activity生命周期方式及案例讲解

Posted datian1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了监听Activity生命周期方式及案例讲解相关的知识,希望对你有一定的参考价值。

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

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

以上是关于监听Activity生命周期方式及案例讲解的主要内容,如果未能解决你的问题,请参考以下文章

Android Activity生命周期及启动模式

android activity中监听View测量完成的4种方式

Android dialog实现监听生命周期

让对象监听 Activity 生命周期事件?

Activity的生命周期及常见回调顺序

Activity的生命周期