1. 程式人生 > >Android應用前後臺切換的判斷

Android應用前後臺切換的判斷

 最近的專案有個需求,需要檢測應用按Home鍵切到後臺,以及點選桌面圖示重新進入前臺的狀態。Android中沒有提供一個應用前後臺切換的回撥或廣播,這個功能只能我們自己來處理。以前遇到這個問題的處理方式是,實現一個BaseActivity,然後讓其他所有Activity都繼承自它,然後在生命週期函式中做相應的檢測。具體檢測方法如下:

       在Activity的onStart和onStop方法中進行計數,計數變數為count,在onStart中將變數加1,onStop中減1,假設應用有兩個Activity,分別為A和B。

       情況一、首先啟動A,A再啟動B:啟動A,count=1,A啟動B,生命週期的順序為B.onStart->A.onStop,count的計數仍然為1。

       情況二、首先啟動A,然後按Home鍵返回桌面:啟動A,count=1,按Home鍵返回桌面,會執行A.onStop,count的計數變位0。

       從上面的兩種情況看出,可以通過對count計數為0,來判斷應用被從前臺切到了後臺。同樣的,從後臺切到前臺也是類似的道理。具體實現看後面的程式碼。

       但是如果專案中不是所有的Activity都繼承自同一個BaseActivity,就無法實現這個功能了。幸運的是,Android在API 14之後,在Application類中,提供了一個應用生命週期回撥的註冊方法,用來對應用的生命週期進行集中管理,這個介面叫registerActivityLifecycleCallbacks,可以通過它註冊自己的ActivityLifeCycleCallback,每一個Activity的生命週期都會回撥到這裡的對應方法。其實這個註冊方法的本質和我們實現BaseActivity是一樣的,只是將生命週期的管理移到了Activity本身的實現中。

       具體使用方法如下:

public class MyApplication extends Application{
    public int count = 0;
    @Override
    public void onCreate() {
        super.onCreate();
 
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
 
            @Override
            public void onActivityStopped(Activity activity) {
                Log.v("viclee", activity + "onActivityStopped");
                count--;
                if (count == 0) {
                    Log.v("viclee", ">>>>>>>>>>>>>>>>>>>切到後臺  lifecycle");
                }
            }
 
            @Override
            public void onActivityStarted(Activity activity) {
                Log.v("viclee", activity + "onActivityStarted");
                if (count == 0) {
                    Log.v("viclee", ">>>>>>>>>>>>>>>>>>>切到前臺  lifecycle");
                }
                count++;
            }
 
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                Log.v("viclee", activity + "onActivitySaveInstanceState");
            }
 
            @Override
            public void onActivityResumed(Activity activity) {
                Log.v("viclee", activity + "onActivityResumed");
            }
 
            @Override
            public void onActivityPaused(Activity activity) {
                Log.v("viclee", activity + "onActivityPaused");
            }
 
            @Override
            public void onActivityDestroyed(Activity activity) {
                Log.v("viclee", activity + "onActivityDestroyed");
            }
 
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                Log.v("viclee", activity + "onActivityCreated");
            }
        });
    }
}

   除此之外,有沒有其他方法可以實現這個功能呢?

       當應用切到後臺的時候,執行在前臺的程序由我們的app變成了桌面app,依據這一點,我們可以實現檢測應用前後臺切換的功能。在Activity的onStop生命週期中執行檢測程式碼,如果發現當前執行在前臺的程序不是我們自己的程序,說明應用切到了後臺。

       想想為什麼要在onStop中檢測,而不是onPause?這是由於A啟動B時,生命週期的執行順序如下:A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop,也就是說,在A的onPause方法中,B的生命週期還沒有執行,程序沒有進入前臺,當然是檢測不到的。我們把程式碼移到onPause生命週期中,發現確實沒有效果。

       具體實現程式碼如下:

  //用來控制應用前後臺切換的邏輯
    private boolean isCurrentRunningForeground = true;
    @Override
    protected void onStart() {
        super.onStart();
        if (!isCurrentRunningForeground) {
            Log.d(TAG, ">>>>>>>>>>>>>>>>>>>切到前臺 activity process");
        }
    }
 
    @Override
    protected void onStop() {
        super.onStop();
        isCurrentRunningForeground = isRunningForeground();
        if (!isCurrentRunningForeground) {
            Log.d(TAG,">>>>>>>>>>>>>>>>>>>切到後臺 activity process");
        }
    }
 
    public boolean isRunningForeground() {
        ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcessInfos = activityManager.getRunningAppProcesses();
        // 列舉程序
        for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessInfos) {
            if (appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                if (appProcessInfo.processName.equals(this.getApplicationInfo().processName)) {
                    Log.d(TAG,"EntryActivity isRunningForeGround");
                    return true;
                }
            }
        }
        Log.d(TAG, "EntryActivity isRunningBackGround");
        return false;
    }

相關推薦

Android應用前後臺切換判斷

 最近的專案有個需求,需要檢測應用按Home鍵切到後臺,以及點選桌面圖示重新進入前臺的狀態。Android中沒有提供一個應用前後臺切換的回撥或廣播,這個功能只能我們自己來處理。以前遇到這個問題的處理方式是,實現一個BaseActivity,然後讓其他所有Activity都繼承

Android】App應用前後臺切換的一種監聽方法

Android本身並沒有提供監聽App的前後臺切換操作的方法。最近看到一種簡單巧妙的方法來監聽前後臺,這裡分享記錄一下。 一、Activity生命週期 我們知道在Android中,兩個Activity,分別為A和B。假設此時A在前臺,當A啟動B時,他們倆之間的生命週期關係如下,可

應用前後臺切換,Application registerActivityLifecycleCallbacks(API 14)-Android

registerActivityLifecycleCallbacks與ActivityLifecycleCallbacks? -- 需求: 1.統計App的停留時間registerActivityLifecycleCallbacks(); 2.統計App中某個Act

[Android]應用語言切換的三種方法

    Android對國際化與多語言切換已經做得不錯了,一個應用只要命名相應語系的values-[language]資料夾,通過“設定”→“語言&鍵盤”→“選擇語言”即可實現應用多種語言的切換。        但如何在應用裡自己實現?搜尋過發現網上有如下的做法:

Android應用主題切換詳解

今日科技快訊昨天,小米董事長、CEO雷軍的母校武漢大學召開新品釋出會,正式推出小米6X,該機售價

android 判斷App程序是否存在,處在前臺,後臺,前後臺切換,service是否執行,設定為系統app

1.判斷程序是否存在 //判斷是否在主程序,這個方法判斷程序名或者pid都可以,如果程序名一樣那pid肯定也一樣 //true:當前程序是主程序 false:當前程序不是主程序 public boolean isUIProcess() { ActivityManager

Android 應用在後臺時,跳轉 Activity 會自動切換應用至前臺

本部落格 demo 見:demo。 平常用手機的時候經常碰到這種情況,用首屏廣告舉個栗子~很多應用都會有首屏廣告 activity A,假設此應用是 app C,如果此時要使用別的應用,就會使得 app C 在後臺執行。可是當 

Android 實現微信,QQ的程式前後臺切換 back鍵切換後臺 點選通知欄恢復前臺

                實現類似微信,QQ的前後臺切換:back鍵切換後臺;點選通知欄恢復前臺。1、back鍵切換後臺的實現:這個實現需要在主activity重寫onbackpressed()方法。程式碼如下:@Override    public void onBackPressed() {    

android 6之前版本判斷應用是否有某個許可權

1) 判斷應用是否具有某個許可權 PackageManager pm = getPackageManager(); boolean permission = (PackageManager.PERMISSION_GRANTED ==

Android應用:橫豎屏切換總結

        眨眼間,已經到了2016你年春節前,離上一篇部落格的時間已經有6個月多,回想起這半年的種種,不得不說,學習和工作實在是太忙了,或許這就是程式設計師的真實寫照吧。         寫部落格之初,主要的目的還是為了把自己的學習痕跡記錄下來,寫的東西比較基礎,也不

Android應用從後臺切換到前臺因為資料被GC報異常

問題情景:     我們的應用在前臺執行,無論怎麼測試,我們的應用都是正常沒問題的,這時按下home鍵,手機回到桌面,我們的應用進入後臺,過了一段時間,我們把應用從後臺切換回前臺,這時測試時發現應用崩

android實現只切換應用的語言(不切換android 系統語言)

android 應用支援國際化語言的配置。  在android 工程中的res資料夾下 建立values-國家程式碼,例如values-en,values-zh 這樣就可以和android 系統中設定的語言 進行匹配, 如沒有匹配上, 則會預設使用values資料夾中的資源

如何判斷 兩個不同包名的 Android 應用的 Apk 簽名是否一致

假定安裝了JDK,如果想查HelloWorld.apk所使用的簽名的fingerprint,可以這樣做: 1. 查詢apk裡的rsa檔案 (Windows) > jar tf HelloWorld.apk |findstr RSA (Linux) $ jar tf HelloWorld.apk |gr

iOS應用程式的生命週期及前後臺切換,應用的各種狀態)

一、iOS應用程式狀態機一共有五種狀態:   1. Not running(未執行):應用還沒有啟動,或者應用正在執行但是途中被系統停止。   2. Inactive(未啟用):當前應用正在前臺執行,但是並不接收事件(當前或許正在執行其它程式碼)。一般每當應用要從一個狀

Android之後臺服務判斷應用Activity是否處於棧頂

在Android開發中,我們經常想知道是否自己的服務處於後臺執行中,因為在後臺執行的伺服器優先順序會降低,也就極有可能會被系統給回收掉,有什麼好辦法呢?Google推薦我們將服務執行到前臺,如何知道服務是否處於後臺執行呢?可以通過獲取堆疊資訊中棧頂的Activity是否為本

Android國際化問題以及在應用切換不同語言設定

一年又一年,16年過去了,17年馬上到來。。。跑偏了,寫博文了 在專案中要做國際化適配,為了更好的切換語言,需要在應用中新增語言切換功能,就像微信那樣 基本適配 先說說國際化適配,其實很簡單,就是將專案中用到的字串資源放在strings.xml資原始檔中,在佈局檔案中通過

Android應用新增(建立)和刪除及判斷是否存在桌面快捷方式

Android桌面程式提供了應用新增和刪除桌面快捷方式的功能以及判斷快捷方式是否存在,只要傳入快捷方式標題、圖示及點選快捷方式執行的應用Intent即可。程式碼如下: /** * 為當前應用新增桌面快捷方式 * * @param cx * @param appNa

Android應用程式內部切換語言及自定義語言

前言:這是小弟的第一篇部落格,琢磨了半天也不知道這玩意怎麼使,因此必然會有很多不足的地方,希望大家多多指點,謝謝! 國際化一直以來也是Android專案中需要考慮到的一個問題,以往我們所接觸到的國際化無非就是在res目錄下新建幾個values資料夾,裡面存放對

android監聽前後臺切換

公司的需求是這樣的,APP切換到前臺是向伺服器傳送資料,切換到後臺是也傳送資料。網上這方面的方法很多也很雜,還不好用,這裡介紹一種完美的解決方法,無論是back鍵還是home鍵切換到後臺都可以監聽,甚至通過後臺殺死APP程序都逃不過。 首先寫一個工具類:

android應用開發之Activity的簡單佈局切換

Activity到底是什麼怎麼用,到現在感覺心裡還是沒底的,說不太清楚,看文件的時候發現一大堆方法,這裡我只寫了簡單佈局的切換,至於以後Activity的用法方法,我會慢慢學習的。 1、什麼是activity Activity是一種互動的介面,一個介面