fix
lmw
2025-03-04 449bdb5d2b5bf7b272ca5cda4c066f9a65040064
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.lzf.easyfloat.utils
 
import android.app.Activity
import android.app.Application
import android.os.Bundle
import com.lzf.easyfloat.core.FloatingWindowManager
import com.lzf.easyfloat.enums.ShowPattern
import java.lang.ref.WeakReference
 
/**
 * @author: liuzhenfeng
 * @function: 通过生命周期回调,判断系统浮窗的过滤信息,以及app是否位于前台,控制浮窗显隐
 * @date: 2019-07-11  15:51
 */
internal object LifecycleUtils {
 
    lateinit var application: Application
    private var activityCount = 0
    private var mTopActivity: WeakReference<Activity>? = null
 
    fun getTopActivity(): Activity? = mTopActivity?.get()
 
    fun setLifecycleCallbacks(application: Application) {
        this.application = application
        application.registerActivityLifecycleCallbacks(object :
            Application.ActivityLifecycleCallbacks {
 
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
 
            override fun onActivityStarted(activity: Activity) {
                // 计算启动的activity数目
                activity?.let { activityCount++ }
            }
 
            override fun onActivityResumed(activity: Activity) {
                activity?.let {
                    mTopActivity?.clear()
                    mTopActivity = WeakReference<Activity>(it)
                    // 每次都要判断当前页面是否需要显示
                    checkShow(it)
                }
            }
 
            override fun onActivityPaused(activity: Activity) {}
 
            override fun onActivityStopped(activity: Activity) {
                activity?.let {
                    // 计算关闭的activity数目,并判断当前App是否处于后台
                    activityCount--
                    checkHide(it)
                }
            }
 
            override fun onActivityDestroyed(activity: Activity) {}
 
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        })
    }
 
    /**
     * 判断浮窗是否需要显示
     */
    private fun checkShow(activity: Activity) =
        FloatingWindowManager.windowMap.forEach { (tag, manager) ->
            manager.config.apply {
                when {
                    // 当前页面的浮窗,不需要处理
                    showPattern == ShowPattern.CURRENT_ACTIVITY -> return@apply
                    // 仅后台显示模式下,隐藏浮窗
                    showPattern == ShowPattern.BACKGROUND -> setVisible(false, tag)
                    // 如果没有手动隐藏浮窗,需要考虑过滤信息
                    needShow -> setVisible(activity.componentName.className !in filterSet, tag)
                }
            }
        }
 
    /**
     * 判断浮窗是否需要隐藏
     */
    private fun checkHide(activity: Activity) {
        // 如果不是finish,并且处于前台,无需判断
        if (!activity.isFinishing && isForeground()) return
        FloatingWindowManager.windowMap.forEach { (tag, manager) ->
            // 判断浮窗是否需要关闭
            if (activity.isFinishing) manager.params.token?.let {
                // 如果token不为空,并且是当前销毁的Activity,关闭浮窗,防止窗口泄漏
                if (it == activity.window?.decorView?.windowToken) {
                    FloatingWindowManager.dismiss(tag, true)
                }
            }
 
            manager.config.apply {
                if (!isForeground() && manager.config.showPattern != ShowPattern.CURRENT_ACTIVITY) {
                    // 当app处于后台时,全局、仅后台显示的浮窗,如果没有手动隐藏,需要显示
                    setVisible(showPattern != ShowPattern.FOREGROUND && needShow, tag)
                }
            }
        }
    }
 
    fun isForeground() = activityCount > 0
 
    private fun setVisible(isShow: Boolean = isForeground(), tag: String?) =
        FloatingWindowManager.visible(isShow, tag)
 
}