首页 > 其他分享 >监听Activity生命周期方式及案例讲解

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

时间:2023-06-19 12:04:48浏览次数:38  
标签:生命周期 Fragment void 添加 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
        }
    }

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


标签:生命周期,Fragment,void,添加,Activity,监听
From: https://blog.51cto.com/u_16163442/6512307

相关文章

  • 【Android】一文读懂 Activity 的生命周期
    作为Android开发人,如果说连Activity生命周期都没搞懂,会走非常多的弯路,所以这篇文章我就对Activity生命周期的生命周期进行一个简单的总结。单Activity生命周期的整体流程首先,我们创建一个My_A_Activity,并且打印它的各个生命周期方法。classMy_A_Activity:AppCompatActivity(){......
  • setContentView(R.layout.activity_);ui->setupUi(this);
    publicclassTutorialPartIIIextendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//setContentView(R.layout.activity_tutorial_part_iii);//*......
  • ActiveMQ InactivityIOException: Channel was inactive for too (>30000) long 处理
    生产服务器上,MQProduce和consumer端同时报如下错误,导致不能正常工作。Transport(tcp://132.97.122.168:61616)failed,reason:org.apache.activemq.transport.InactivityIOException:Channelwasinactivefortoo(>30000)long:tcp://132.97.122.168:61616,attemptingt......
  • Android中启动Activity的最佳写法
    问题思考在实际工作场景中,大家各个模块都是有交互的,那么就存在各个模块Activity的相互跳转。假设小A负责一个ActivityA,所有跳转到ActivityA的请求都需要携带String类型的参数resaon,那么每一个对接跳转到ActivityA的业务,小A都要说一遍:“跳转过来需要带一个参数reason”,很明显这种......
  • IIS配置代理转发到Apache或其他端口监听服务
    目标:iis运行asp程序;Apache运行php,iis监听占用80端口,由iis转发代理到Apache的php应用;iis转发到其他应用,如tornado服务。iis配置代理转发及路由重写https://iis-umbraco.azurewebsites.net/downloads官网下载Urlrewrite和ApplicationrequestRouter两个exe并安装选择上面安装......
  • UIViewController生命周期方法viewDidLoad、viewWillAppear和viewDidAppear
    UIViewController生命周期方法viewDidLoad、viewWillAppear和viewDidAppear 这3个方法执行顺序为:viewDidLoad-》viewWillAppear-》viewDidAppear  viewDidLoadCalledaftertheviewhasbeenloaded.Forviewcontrollerscreatedincode,thisisafter-loadView.Forviewc......
  • Fedora Linux 36生命周期结束
    红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,同时所有推送到稳定版的Fedora Linux 36更新也将停止。红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,......
  • Fedora Linux 36生命周期结束
    红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,同时所有推送到稳定版的Fedora Linux 36更新也将停止。红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,......
  • Fedora Linux 36生命周期结束
    红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,同时所有推送到稳定版的Fedora Linux 36更新也将停止。红帽软件工程师KevinFenzi宣布,Fedora36已在5月16日结束生命周期,官方不再提供安全补丁和功能更新,......
  • iOS程序运行生命周期
    iOS程序运行生命周期  在文件AppDelegate.m中定义了iOS程序运行的各个生命周期,清楚了解程序运行中的每个生命周期,对于我们的开发工作将提供极大的帮助。下面代码就是AppDelegate.m中各生命周期对应的方法。 -(BOOL)application:(UIApplication*)applicationdidFinishLaunch......