Android中判斷App是處于前臺(tái)還是后臺(tái)

Android_Banner.jpg

簡(jiǎn)介

有時(shí)候我們需要判斷App是處于前臺(tái)還是后臺(tái),這樣有利于我們處理一些業(yè)務(wù)
這里就說(shuō)下如何判斷App是處于前臺(tái)還是后臺(tái)
分別通過(guò)RunningTasks,RunningProcess 以及ActivityLifecycleCallbacks

實(shí)現(xiàn)

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以上已經(jīng)被廢棄,只會(huì)返回自己和系統(tǒng)的一些不敏感的task,不再返回其他應(yīng)用的task,用此方法來(lái)判斷自身App是否處于后臺(tái)仍然有效,但是無(wú)法判斷其他應(yīng)用是否位于前臺(tái),因?yàn)椴荒茉佾@取信息。

RunningProcess
/**
     * 判斷當(dāng)前應(yīng)用是否處于前臺(tái)
     */
    private fun isAppForeground(): Boolean {
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        /**
         * 存活的App進(jìn)程
         */
        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
    }
 /**
     * 用于判斷那個(gè)應(yīng)用是處于前臺(tái)的
     */
    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之后已經(jīng)被廢棄。

例如,在聊天類型的App中,常常需要常駐后臺(tái)來(lái)不間斷地獲取服務(wù)器的消息,就需要把Service設(shè)置成START_STICKY,kill后會(huì)被重啟(等待5s左右)來(lái)保證Service常駐后臺(tái)。如果Service設(shè)置了這個(gè)屬性,這個(gè)App的進(jìn)程就會(huì)被判斷為前臺(tái)。代碼表現(xiàn)為

appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND

上述code永遠(yuǎn)成立,這樣就永遠(yuǎn)無(wú)法判斷到底那個(gè)是前臺(tái)了。

ActivityLifecycleCallbacks

這里我們對(duì)ActivityLifecycleCallbacks的實(shí)現(xiàn)類做了一層封裝,利用高階函數(shù),當(dāng)我們需要去實(shí)現(xiàn)那個(gè)聲明周期的回調(diào)的時(shí)候,就通過(guò)高階函數(shù)來(lái)提供回調(diào)處理,否則默認(rèn)不做任何處理

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的實(shí)際數(shù)值返回回去
     */
    fun getCount():Int = mCount
}

然后我們?cè)贏pplication的onCreate中進(jìn)行注冊(cè)

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
        //注冊(cè)生命周期回調(diào)事件
        registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
    }

    /**
     * 用于判斷當(dāng)前進(jìn)程是否處于前臺(tái)
     */
    fun isForegroundMethod(): Boolean = mActivityLifecycleCallbacks.getCount() > 0


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

當(dāng)我們不管是點(diǎn)擊Back鍵還是Home鍵都會(huì)回調(diào)到onStop方法,我們?cè)趏nStart和onStop中分別對(duì)mCount值做了加減
這樣我們可以通過(guò)該數(shù)值來(lái)判斷當(dāng)前App是否處于前臺(tái)還是后臺(tái)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容