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