1. 程式人生 > >APP怎麼判斷自己是處於前臺還是後臺

APP怎麼判斷自己是處於前臺還是後臺

RunningTask

原理:
當一個 App 處於前臺的時候,會處於 RunningTask 的這個棧的棧頂,所以我們可以取出 RunningTask 的棧頂的任務程序,看他與我們的想要判斷的 App 的包名是否相同,來達到效果

缺點:
getRunningTask 方法在 Android5.0 以上已經被廢棄,只會返回自己和系統的一些不敏感的 task,不再返回其他應用的 task,用此方法來判斷自身 App 是否處於後臺,仍然是有效的,但是無法判斷其他應用是否位於前臺,因為不再能獲取資訊

<uses-permission android:name="android.permission.GET_TASKS"
/>
    public static boolean isApplicationBroughtToBackground(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0
).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { return true; } } return false; }

RunningProcess

原理
通過 runningProcess 獲取到一個當前正在執行的程序的 List,我們找到與想要判斷app包名一樣的程序並判斷這個程序的 importance 屬性是否是前臺程序,如果是那這個 App 就處於前臺
缺點:
在聊天型別的 App 中,常常需要常駐後臺來不間斷的獲取伺服器的訊息,這就需要我們把 Service 設定成 START_STICKY,kill 後會被重啟(等待 5 秒左右)來保證 Service 常駐後臺。如果 Service 設定了這個屬性,這個 App 的程序就會被判斷是前臺,程式碼上的表現就是 appProcess.importance 的值永遠是 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,這樣就永遠無法判斷出到底哪個是前臺了。

  public static boolean isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context.getPackageName())) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                    Log.i("後臺", appProcess.processName);
                    return true;
                }else{
                    Log.i("前臺", appProcess.processName);
                    return false;
                }
            }
        }
        return false;
    }

ActivityLifecycleCallbacks

public class Application extends ContextWrapper implements ComponentCallbacks2 {
    。。。
    public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }
    。。。
}

Application類裡有ActivityLifecycleCallbacks回撥介面,我們在Application的onCreate()註冊該介面。

一個app內從ActivityA跳轉到ActivityB的回撥方法如下:
A.onPause() -> B.onStart() -> B.onResume() -> A.onStop()

通過這些回撥我們可以在onStart()和onStop()中進行計數,如果start就+1,onstop就-1,這樣可以根據計數是否為0來判斷是否是前臺了。

/proc目錄下的process程序資訊

原理:
Linux系統核心會把process程序資訊儲存在/proc目錄下,Shell命令去獲取的他,再根據程序的屬性判斷是否為前臺。
優點:
不需要任何許可權
可以判斷任意一個應用是否在前臺,而不侷限在自身應用
缺點:
當/proc下資料夾過多時,此方法是耗時操作