一、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(); } }