zoukankan      html  css  js  c++  java
  • 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();
        }
    }
  • 相关阅读:
    js中的replace 回车符
    HttpHandler 读取Session
    [原]vs2005 修改新增文件时的默认编码方式
    系统托盘NotifyIcon控件及右键菜单功能
    addAttribute
    gpibCmd
    deviceFactory
    string is
    TitledMotorEntry TitledFrame MotorViewEntry TitleMotorEntry
    IOC port
  • 原文地址:https://www.cnblogs.com/renhui/p/11074604.html
Copyright © 2011-2022 走看看