• Android监听应用切换到后台和前台


    一个是注册监听

    1. @HiltAndroidApp
    2. class MyApplication :Application{
    3. constructor() : super()
    4. override fun onCreate() {
    5. super.onCreate()
    6. Log.e("MyApplication","=====MyApplication")
    7. registerActivityLifecycleCallbacks(activityLifecycleCallbacks)
    8. }
    9. val activityLifecycleCallbacks:ActivityLifecycleCallbacks= object:ActivityLifecycleCallbacks{
    10. private var activityStartCount = 0
    11. override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
    12. }
    13. override fun onActivityStarted(activity: Activity) {
    14. activityStartCount++
    15. if(activityStartCount==1){
    16. //从后台切换到前台
    17. }
    18. }
    19. override fun onActivityResumed(activity: Activity) {
    20. }
    21. override fun onActivityPaused(activity: Activity) {
    22. }
    23. override fun onActivityStopped(activity: Activity) {
    24. activityStartCount--
    25. if (activityStartCount == 0){
    26. //从前台切换到后台
    27. }
    28. }
    29. override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
    30. }
    31. override fun onActivityDestroyed(activity: Activity) {
    32. }
    33. }
    34. }
    registerActivityLifecycleCallbacks(activityLifecycleCallbacks)这个是监听所有的activity的生命周期的,为什么能做到呢?接下来我们慢慢分析。
    ActivityLifecycleCallbacks是Application一个内部的接口。

    Application提供了

    registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)
    unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback)

    两个方法。

    我们分析其中registerActivityLifecycleCallbacks()方法

    1. public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
    2. synchronized (mActivityLifecycleCallbacks) {
    3. mActivityLifecycleCallbacks.add(callback);
    4. }
    5. }

    发现是将接口的实现添加到Application的一个集合中

    private ArrayList mActivityLifecycleCallbacks =
            new ArrayList();

    这又是一个典型的观察者模式。

    那这个集合肯定是在哪里调用的呢?全局搜索发现在这个方法中转成了数组

    1. @UnsupportedAppUsage
    2. private Object[] collectActivityLifecycleCallbacks() {
    3. Object[] callbacks = null;
    4. synchronized (mActivityLifecycleCallbacks) {
    5. if (mActivityLifecycleCallbacks.size() > 0) {
    6. callbacks = mActivityLifecycleCallbacks.toArray();
    7. }
    8. }
    9. return callbacks;
    10. }

    这个数组又在application中的

    dispatchActivityCreated
    dispatchActivityStarted
    dispatchActivityResumed

    等方法中被调用,如下所示:

    1. /* package */ void dispatchActivityDestroyed(@NonNull Activity activity) {
    2. Object[] callbacks = collectActivityLifecycleCallbacks();
    3. if (callbacks != null) {
    4. for (int i=0; i
    5. ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity);
    6. }
    7. }
    8. }

    上面的几个方法明显对应的是activity的生命周期,那么很显然这些方法肯定是得在activity的生命周期中调用,不然是无法监听activity的生命周期的。我们到activity的最parent的Activity中去寻找。

    我们分析其中

    Resume的一个生命周期(其他的大同小异),如下所示:
    1. protected void onResume() {
    2. if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
    3. dispatchActivityResumed(); //调用这方法
    4. mActivityTransitionState.onResume(this);
    5. enableAutofillCompatibilityIfNeeded();
    6. if (mAutoFillResetNeeded) {
    7. if (!mAutoFillIgnoreFirstResumePause) {
    8. View focus = getCurrentFocus();
    9. if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
    10. // TODO(b/148815880): Bring up keyboard if resumed from inline authentication.
    11. // TODO: in Activity killed/recreated case, i.e. SessionLifecycleTest#
    12. // testDatasetVisibleWhileAutofilledAppIsLifecycled: the View's initial
    13. // window visibility after recreation is INVISIBLE in onResume() and next frame
    14. // ViewRootImpl.performTraversals() changes window visibility to VISIBLE.
    15. // So we cannot call View.notifyEnterOrExited() which will do nothing
    16. // when View.isVisibleToUser() is false.
    17. getAutofillManager().notifyViewEntered(focus);
    18. }
    19. }
    20. }
    21. notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_RESUME);
    22. mCalled = true;
    23. }

     果然是调用了Application中对象的方法

    1. // getApplication().dispatchActivityResumed(this); 调用了Application中的分发方法
    2. private void dispatchActivityResumed() {
    3. getApplication().dispatchActivityResumed(this);
    4. Object[] callbacks = collectActivityLifecycleCallbacks();
    5. if (callbacks != null) {
    6. for (int i = 0; i < callbacks.length; i++) {
    7. ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityResumed(this);
    8. }
    9. }
    10. }

    2.利用Lifecycle的扩展方法

    添加依赖:
     

    1. //只能适用于androidX项目
    2. implementation("androidx.lifecycle:lifecycle-process:2.2.0")

    在mainActivity或者application中添加如下代码: 

    1. ProcessLifecycleOwner.get().lifecycle.addObserver(object:DefaultLifecycleObserver{
    2. override fun onStop(owner: LifecycleOwner) {
    3. super.onStop(owner)
    4. //后台
    5. }
    6. override fun onStart(owner: LifecycleOwner) {
    7. super.onStart(owner)
    8. //前台
    9. }
    10. })

  • 相关阅读:
    [NET毕业设计源码]基于NET实现的旅游景点推荐系统[包运行成功]
    22/6/27
    rtsp转webrtc的其他几个项目
    【GitLab私有仓库】在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透
    一文带你悉知JDBC
    【PDF提取页面】使用Adobe Acrobat提取PDF文档的某几个页面另存
    SpringBoot的创建与配置文件【.properties与.yml】
    idea Springboot 高校科研资源共享系统VS开发mysql数据库web结构java编程计算机网页源码maven项目
    ArcGIS批量出图操作流程(附练习数据下载)
    浅谈西门子Camstar MES桌面端开发
  • 原文地址:https://blog.csdn.net/xueyoubangbang/article/details/126349048