美文网首页Android其他重要点基础小问题延后2
Android 如何优雅的实现App 前后台状态变化通知

Android 如何优雅的实现App 前后台状态变化通知

作者: 不思进取的码农 | 来源:发表于2021-05-27 16:40 被阅读0次

    原文链接:Coobox 之 App 前后台状态变化通知

    如何定义前后台

    • 这里的前后台不是 Linux 进程的前后台(Foreground, Backgroud)
    • App 前台状态指的是 当用户可以肉眼可见 App 的界面(Activity),否则为 App 后台状态

    如何实现

    • 定义一个当前进程的 Activity数量变量,如activityCount, Int类型
    • 当进程中的 Activity 执行到 onStart 方法,执行activityCount++
    • 当进程中的 Activity 执行到 onStop 方法,执行activityCount--
    • 当activityCount 为 0, 则表示 App 在后台状态,否则为前台状态

    使用简介

    监听 前后台 状态变化
    AppStateHelper.addListener(object: OnAppStateChangedListener {
        override fun onAppStateChanged(state: AppStateHelper.Message, activity: Activity) {
          Log.i("AppStateHelper", "onAppStateChanged message=$state;activity=$activity")
        }
    })
    
    

    手动触发调用

    class AppStateTestFragment : TestableFragment(), OnAppStateChangedListener {
        override fun addTestItems() {
        }
    
        fun setupAppStateHelper(application: Application) {
            application.registerActivityLifecycleCallbacks(object: ActivityLifecycleCallbacksImpl() {
                override fun onActivityStarted(activity: Activity) {
                    super.onActivityStarted(activity)
                    AppStateHelper.activityStarting(activity)
                }
    
                override fun onActivityStopped(activity: Activity) {
                    super.onActivityStopped(activity)
                    AppStateHelper.activityStopping(activity)
                }
            })
        }
    }
    

    查询前后台状态

    // App是否为前台状态
    val isForeground = AppStateHelper.isForeground
    
    // App 是否为后台状态
    val isBackground = AppStateHelper.isBackground
    
    // App 的状态
    val appState = AppStateHelper.state
    

    实现代码

    package com.secoo.coobox.library.lifecycle
    
    import android.app.Activity
    
    
    object AppStateHelper {
        private var activityCount = 0
        private val listeners = mutableListOf<OnAppStateChangedListener>()
    
        /**
         * 判断 App 当前是否为前台可见状态
         */
        val isForeground: Boolean
            get() = activityCount != 0
    
        /**
         * 判断 App 当前是否为后台不可见状态
         */
        val isBackground: Boolean
            get() = activityCount == 0
    
    
        enum class Message {
            BACKGROUNDED, FOREGROUNDED
        }
    
        /**
         * 返回当前的App状态
         * @return
         */
        val state: Message
            get() = if (isForeground) {
                Message.FOREGROUNDED
            } else {
                Message.BACKGROUNDED
            }
    
        /**
         * Activity 执行到 onStart 时调用,需主动调用
         */
        fun activityStarting(activity: Activity): Boolean {
            var ret = false
            if (activityCount == 0) {
                onForeground(activity)
                ret = true
            }
            activityCount++
            return ret
        }
    
        /**
         * Activity 执行到 onStop 时调用,需主动调用
         * */
        @Synchronized
        fun activityStopping(activity: Activity): Boolean {
            activityCount--
            if (activityCount == 0) {
                onBackground(activity)
                return true
            }
            return false
        }
    
        fun addListener(listener: OnAppStateChangedListener) {
            listeners.add(listener)
        }
    
        fun removeListener(listener: OnAppStateChangedListener) {
            listeners.remove(listener)
        }
    
        private fun onBackground(activity: Activity) {
            listeners.forEach {
                it.onAppStateChanged(Message.BACKGROUNDED, activity)
            }
        }
    
        private fun onForeground(activity: Activity) {
            listeners.forEach {
                it.onAppStateChanged(Message.FOREGROUNDED, activity)
            }
        }
    
    }
    

    这是一款纯kotlin的工具库,内部有更丰富的功能,欢迎大家star

    如何引入

    相关文章

      网友评论

        本文标题:Android 如何优雅的实现App 前后台状态变化通知

        本文链接:https://www.haomeiwen.com/subject/oagxsltx.html