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

 

更多相关文章

  1. 如何在后台运行Linux命令?
  2. 三种自定义漂亮的Android(安卓)SeekBar的方法
  3. 深入了解Android图形管道-part1
  4. android新增语言的方法(墨西哥的西班牙语)
  5. Android反编译工具apktool
  6. Android学习笔记-ProgressBar和ListView使用方法(一)
  7. Android(安卓)Studio 断点调试和高级调试
  8. Android(安卓)TestView获取每一行文字的方法
  9. Android(安卓)1.5 1.6 2.0 2.1 2.2 2.3 3.0,4.0的区别

随机推荐

  1. Android模拟器
  2. Android自定义Transition动画
  3. 进入android项目组的第一天
  4. Android(安卓)Studio签名打包应用
  5. android Animation
  6. The difference between '?attr' between
  7. Android中对Log日志文件的分析
  8. Android基础(一)
  9. android selector
  10. Android实现2D翻转动画