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下資料夾過多時,此方法是耗時操作