Android使用ActivityLifecycleCallbacks管理Activity和區分App前后台


一、ActivityLifecycleCallbacks接口介紹

官方地址:https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks

在 Android API 14之后的Application類中,為我們提供了一個應用生命周期回調的注冊方法,用來對應用的生命周期進行集中管理,這個接口叫registerActivityLifecycleCallbacks,可以通過它注冊自己的ActivityLifeCycleCallback,每一個Activity的生命周期都會回調到這里的對應方法。

有了ActivityLifeCycleCallback接口,我們就可以完成之前我們想做的類似限制制定Activity個數等相關需求,因為所有Activity的生命周期都會在這里回調,我們可以根據條件隨心處理。

Activity 的生命周期圖為:https://developer.android.com/images/activity_lifecycle.png

ActivityLifecycleCallbacks 的方法列表文檔:https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks

兩者幾乎是一一對應的,不管是做Activity的限制還是Activity的狀態統計都是非常方便的,而且里面還有一個void onActivitySaveInstanceState(Activity activity, Bundle outState) 方法,非常方便我們來保存Activity狀態數據。

使用ActivityLifecycleCallbacks我們可以完成類似如下的功能:

1. 限制指定的Activity的數量

2. 控制在特定情況下只會有一個Activity被打開

3. 判斷App前后台狀態

二、ActivityLifecycleCallbacks的應用

Application.ActivityLifecycleCallbacks是Application中的一個接口,使用起來也很簡單,只需要調用registerActivityLifecycleCallbacks方法即可完成注冊。Application.ActivityLifecycleCallbacks中對應的監聽的生命周期方法會在Activity中的生命方法調用父類的方法之后被觸發。

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;

public class LifecycleApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        init();
    }

    private void init() {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was Created"+"activity==null   "
                        +(activity==null)+"     activity.isFinishing()  "+(activity.isFinishing())+"    activity.isDestroyed()  "+activity.isDestroyed());
            }

            @Override
            public void onActivityStarted(Activity activity) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was Started"+"activity==null   "
                            +(activity==null)+"     activity.isFinishing()   "+(activity.isFinishing())+"   activity.isDestroyed()  "+activity.isDestroyed());
            }

            @Override
            public void onActivityResumed(Activity activity) {
                 Log.e("Lifecycle",activity.getLocalClassName()+" was oResumed"+"activity==null   "
                        +(activity==null)+"activity.isFinishing()   "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
            }

            @Override
            public void onActivityPaused(Activity activity) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was Pauseed"+"activity==null   "
                        +(activity==null)+"activity.isFinishing()   "+(activity.isFinishing())+"activity.isDestroyed()  "+activity.isDestroyed());
            }

            @Override
            public void onActivityStopped(Activity activity) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was Stoped"+"activity==null    "
                        +(activity==null)+"activity.isFinishing()   "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was SaveInstanceState"+"activity==null "
                        +(activity==null)+"activity.isFinishing()   "+(activity.isFinishing())+"activity.isDestroyed()  "+activity.isDestroyed());
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                Log.e("Lifecycle",activity.getLocalClassName()+" was Destroyed"+"activity==null"
                        +(activity==null)+"  activity.isFinishing()  "+(activity.isFinishing())+"  activity.isDestroyed()"+activity.isDestroyed());
            }
        });
    }
}

在清單中聲明Application,無需在Activity添加額外的代碼就可以實現監控:

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    public static final String LIFECYCLE = "MainActivity:Lifecycle";

    @Override
        protected void onCreate(Bundle savedInstanceState) {
        Log.e(LIFECYCLE, "onCreate() is Running__before super.onCreate called");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(LIFECYCLE, "onCreate() is Running__after super.onCreate called");
    }

    @Override
        protected void onRestart() {
        Log.e(LIFECYCLE, "onRestart() is Running__before super's called");
        super.onRestart();
        Log.e(LIFECYCLE, "onRestart() is Running__after super's called");
    }

    @Override
        protected void onStart() {
        Log.e(LIFECYCLE, "onStart() is Running__before super.onStart called");
        super.onStart();
        Log.e(LIFECYCLE, "onStart() is Running__after super.onStart called");
    }

    @Override
        protected void onResume() {
        Log.e(LIFECYCLE, "onResume() is Running__before super.onResume called");
        super.onResume();
        Log.e(LIFECYCLE, "onResume() is Running__after super.onResume called");
    }

    @Override
        protected void onPause() {
        Log.e(LIFECYCLE, "onPause() is Running__before super's called");
        super.onPause();
        Log.e(LIFECYCLE, "onPause() is Running__after super's called");
    }

    @Override
        protected void onStop() {
        Log.e(LIFECYCLE, "onStop() is Running__before super's called");
        super.onStop();
        Log.e(LIFECYCLE, "onStop() is Running__after super's called");
    }

    @Override
        protected void onDestroy() {
        Log.e(LIFECYCLE, "onDestroy() is Running__before super's called");
        super.onDestroy();
        Log.e(LIFECYCLE, "onDestroy() is Running__after super's called");
    }

    public void toTask(View view) {
        startActivity(new Intent(this, TaskActivity.class));
        //finish();
    }
} 

三、使用 ActivityLifecycleCallbacks 判斷App前后台狀態

App 前后台的切換一般情況下都是按Home來進行,當然也有別的方式,但是此時Activity的生命周期是一樣的:

HOME鍵前后台切換Activity的執行順序:onPause->onStop->onRestart->onStart->onResume

BACK鍵前后台切換Activity鍵的順序: onPause->onStop->onDestroy->onCreate->onStart->onResume

其實按BACK按鍵就是退出app了,不算是前台后切換。

現在我們知道App的由前台切換到后台所有打開的Activity會走:

onPause->onStop

后台切換到前台所有打開的Activity會走:

->onRestart->onStart->onResume

前后台切換App所有打開的Activity的生命周期都是一樣的,這樣我就可以在ActivityLifecycleCallbacks回調接口中記錄生命周期:

public class App extends Application {
    //記錄Activity的總個數
    public int count = 0;
    private static App mApp;
    public static Stack<ActivityDetail> store;
    //商品詳情頁最多個數,這里為了測試只寫了2,大家根據自己的情況設值
    private static final int MAX_ACTIVITY_DETAIL_NUM = 2;

    @Override
        public void onCreate() {
        super.onCreate();
        mApp = this;
        store = new Stack<>();
        registerActivityLifecycleCallbacks(new SwitchBackgroundCallbacks());
    }

    public static App getAppContext() {
        return mApp;
    }

    public static boolean toGoodsDetail(String id){

        if(store == null || store.empty()){
            return false;
        }
        for(ActivityDetail activityDetail : store){
            if(id.equalsIgnoreCase(activityDetail.getID())){ //當前商品的詳情頁已經打開
                activityDetail.finish();
                // 這是你需要在AndroidManifest.xml中添加"Android.permission.STOP_APP_SWITCHES"用戶權限,前提是必須是系統應用才可以。
                // ActivityManager am = (ActivityManager) getAppContext().getSystemService(Activity.ACTIVITY_SERVICE);
                // am.moveTaskToFront(activityDetail.getTaskId(), 0);
                return true;
            }
        }
        return false;
    }

    private class SwitchBackgroundCallbacks implements ActivityLifecycleCallbacks {

        @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {
            if(activity instanceof ActivityDetail) {
                if(store.size() >= MAX_ACTIVITY_DETAIL_NUM){
                    store.peek().finish(); //移除棧底的詳情頁並finish,保證商品詳情頁個數最大為10
                }
                store.add((ActivityDetail) activity);
            }
        }

        @Override
            public void onActivityStarted(Activity activity) {
            if (count == 0) { //后台切換到前台
                Log.v("danxx", ">>>>>>>>>>>>>>>>>>>App切到前台");
            }
            count++;
        }

        @Override
            public void onActivityResumed(Activity activity) {

        }

        @Override
            public void onActivityPaused(Activity activity) {

        }

        @Override
            public void onActivityStopped(Activity activity) {
            count--;
            if (count == 0) { //前台切換到后台
                Log.v("danxx", ">>>>>>>>>>>>>>>>>>>App切到后台");
            }
        }

        @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

        }

        @Override
            public void onActivityDestroyed(Activity activity) {
            store.remove(activity);
        }
    }
    // 獲取當前的Activity
    public Activity getCurActivity() {
        return store.lastElement();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM