Android中判断App是处于前台还是后台

Android_Banner.jpg

简介

有时候我们需要判断App是处于前台还是后台,这样有利于我们处理一些业务
这里就说下如何判断App是处于前台还是后台
分别通过RunningTasks,RunningProcess 以及ActivityLifecycleCallbacks

实现

RunningTasks
 private fun getTopApplication() {

        //首先获取到ActivityManager
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

        if (activityManager.getRunningTasks(1) == null) {
            Log.e(TAG, "getForegroundActivity: ")
            return
        }

        var runningTaskInfo = activityManager.getRunningTasks(1)[0]
        if (runningTaskInfo == null) {
            Log.e(TAG, "runningTaskInfo is null")
            return
        }

        runningTaskInfo.topActivity?.let {
            Log.e(TAG, "top application is ${it.packageName}")
        }
    }

getRunningTask方法在5.0以上已经被废弃,只会返回自己和系统的一些不敏感的task,不再返回其他应用的task,用此方法来判断自身App是否处于后台仍然有效,但是无法判断其他应用是否位于前台,因为不能再获取信息。

RunningProcess
/**
     * 判断当前应用是否处于前台
     */
    private fun isAppForeground(): Boolean {
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        /**
         * 存活的App进程
         */
        var runningAppProcesses = activityManager.runningAppProcesses

        if (runningAppProcesses == null) {
            Log.e(TAG, "runningAppProcesses is null")
            return false
        }

        runningAppProcesses.forEach {
            if (it.processName == packageName && (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)) {
                return true
            }
        }
        return false
    }
 /**
     * 用于判断那个应用是处于前台的
     */
    private fun getForegroundApp(): String? {

        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        var runningAppProcesses = activityManager.runningAppProcesses
        if (runningAppProcesses.isNullOrEmpty()) {
            return null
        }

        runningAppProcesses.forEach {

            if (it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND || it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
                return it.processName
            }
        }

        return null
    }

Android5.0之后已经被废弃。

例如,在聊天类型的App中,常常需要常驻后台来不间断地获取服务器的消息,就需要把Service设置成START_STICKY,kill后会被重启(等待5s左右)来保证Service常驻后台。如果Service设置了这个属性,这个App的进程就会被判断为前台。代码表现为

appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND

上述code永远成立,这样就永远无法判断到底那个是前台了。

ActivityLifecycleCallbacks

这里我们对ActivityLifecycleCallbacks的实现类做了一层封装,利用高阶函数,当我们需要去实现那个声明周期的回调的时候,就通过高阶函数来提供回调处理,否则默认不做任何处理

class MyActivityLifecycleCallbacks(
    var onActivityCreatedAction: ((Activity, Bundle?) -> Unit)? = null,
    var onActivityStartedAction: ((Activity) -> Unit)? = null,
    var onActivityResumedAction: ((Activity) -> Unit)? = null,
    var onActivityPausedAction: ((Activity) -> Unit)? = null,
    var onActivityStoppedAction: ((Activity) -> Unit)? = null,
    var onActivitySaveInstanceStateAction: ((Activity, Bundle) -> Unit)? = null,
    var onActivityDestroyedAction: ((Activity) -> Unit)? = null

) : Application.ActivityLifecycleCallbacks {

    private var mCount=0
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        onActivityCreatedAction?.invoke(activity, savedInstanceState)
    }

    override fun onActivityStarted(activity: Activity) {
        mCount++
        onActivityStartedAction?.invoke(activity)
    }

    override fun onActivityResumed(activity: Activity) {
        onActivityResumedAction?.invoke(activity)
    }

    override fun onActivityPaused(activity: Activity) {
        onActivityPausedAction?.invoke(activity)
    }

    override fun onActivityStopped(activity: Activity) {
        mCount--
        onActivityStoppedAction?.invoke(activity)
    }

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        onActivitySaveInstanceStateAction?.invoke(activity, outState)
    }

    override fun onActivityDestroyed(activity: Activity) {
        onActivityDestroyedAction?.invoke(activity)
    }

    /**
     * 这里我们把mCount的实际数值返回回去
     */
    fun getCount():Int = mCount
}

然后我们在Application的onCreate中进行注册

class LifeApplication : Application() {

    private val TAG = "LifeApplication"

    private val mActivityLifecycleCallbacks by lazy {
        MyActivityLifecycleCallbacks(
            onActivityCreatedAction = { activit, bundle ->
                Log.e(TAG, "onCreate: ")


            },
            onActivityStoppedAction = { activity ->

                Log.e(TAG, "onStop ")

            },
            onActivityDestroyedAction = { activity ->
                Log.e(TAG, "onDestroy")

            })
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
        //注册生命周期回调事件
        registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
    }

    /**
     * 用于判断当前进程是否处于前台
     */
    fun isForegroundMethod(): Boolean = mActivityLifecycleCallbacks.getCount() > 0


    companion object{
        private  var  instance :LifeApplication?= null
        fun getInstance () = instance!!
    }

当我们不管是点击Back键还是Home键都会回调到onStop方法,我们在onStart和onStop中分别对mCount值做了加减
这样我们可以通过该数值来判断当前App是否处于前台还是后台

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339