美文网首页androidaudio、video、image我的安卓学习
Android Activity 全局管理 终极解决方案

Android Activity 全局管理 终极解决方案

作者: 极客大白 | 来源:发表于2016-08-04 08:42 被阅读3231次

    Android Activity 全局管理 终极解决方案

    管理Activity的好处

    在Android 开发中 Activity 的管理 对于一个App是至关重要的,管理所有Activity 不仅能实现在应用推出时关闭所有activity,还能实现获取当前Activity上一个Activity、寻找某个类型的Activity、结束某个Activity,以及Activity之间的跳转等多种交互操作。

    传统的实现方式

    之前管理Activity 的方式是在BaseActivity onCreate 方法中将Activity 实例存入工具类 或者BaseActivity 中维护的一个List或stack中,这样能应对多数情况下的问题,但假如有Activity没有继承封装的BaseActivity,那每个Activity 就都要在onCreate方法中写添加到维护list的代码,同时当Activity销毁时,也要从list中将Activity移除,等等,逻辑可谓复杂,代码也较难维护。

    终极解决方案

    所幸的是,自Android 4.0(API-14)开始,Application 中多了一个方法,可以设置全局监听Activity的生命周期。这个方法就是:registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks activityLifecycleCallbacks)在传入的参数 activityLifecycleCallbacks 能得到全局所有Activity 生命周期的回调,因此 我们可以从Application中全局监听所有Activity 并对其进行管理,再也不用在Activity中处理那些扯淡的逻辑,不废话,直接上代码:

    package com.kevin.baselibrary.app;
    
    import android.app.Activity;
    import android.app.Application;
    import android.content.Context;
    import android.os.Build;
    import android.os.Bundle;
    
    import com.kevin.baselibrary.utils.LogUtils;
    
    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * Created by bailiangjin on 16/4/11.
     */
    public abstract class AbsSuperApplication extends Application {
    
        protected static Context context;
        protected static String appName;
    
        /**
         * 维护Activity 的list
         */
        private static List<Activity> mActivitys = Collections
                .synchronizedList(new LinkedList<Activity>());
    
        @Override
        public void onCreate() {
            super.onCreate();
            context = this.getApplicationContext();
            appName =  getAppNameFromSub();
            registerActivityListener();
        }
    
        public static String getAppName() {
            return appName;
        }
    
        public static Context getContext() {
            return context;
        }
    
        protected abstract String  getAppNameFromSub();
    
        /**
         * @param activity 作用说明 :添加一个activity到管理里
         */
        public void pushActivity(Activity activity) {
            mActivitys.add(activity);
            LogUtils.d("activityList:size:"+mActivitys.size());
        }
    
        /**
         * @param activity 作用说明 :删除一个activity在管理里
         */
        public void popActivity(Activity activity) {
            mActivitys.remove(activity);
            LogUtils.d("activityList:size:"+mActivitys.size());
        }
    
        /**
         * get current Activity 获取当前Activity(栈中最后一个压入的)
         */
        public static Activity currentActivity() {
            if (mActivitys == null||mActivitys.isEmpty()) {
                return null;
            }
            Activity activity = mActivitys.get(mActivitys.size()-1);
            return activity;
        }
    
        /**
         * 结束当前Activity(栈中最后一个压入的)
         */
        public static void finishCurrentActivity() {
            if (mActivitys == null||mActivitys.isEmpty()) {
                return;
            }
            Activity activity = mActivitys.get(mActivitys.size()-1);
            finishActivity(activity);
        }
    
        /**
         * 结束指定的Activity
         */
        public static void finishActivity(Activity activity) {
            if (mActivitys == null||mActivitys.isEmpty()) {
                return;
            }
            if (activity != null) {
                mActivitys.remove(activity);
                activity.finish();
                activity = null;
            }
        }
    
        /**
         * 结束指定类名的Activity
         */
        public static void finishActivity(Class<?> cls) {
            if (mActivitys == null||mActivitys.isEmpty()) {
                return;
            }
            for (Activity activity : mActivitys) {
                if (activity.getClass().equals(cls)) {
                    finishActivity(activity);
                }
            }
        }
    
        /**
         * 按照指定类名找到activity
         *
         * @param cls
         * @return
         */
        public static Activity findActivity(Class<?> cls) {
            Activity targetActivity = null;
            if (mActivitys != null) {
                for (Activity activity : mActivitys) {
                    if (activity.getClass().equals(cls)) {
                        targetActivity = activity;
                        break;
                    }
                }
            }
            return targetActivity;
        }
    
        /**
         * @return 作用说明 :获取当前最顶部activity的实例
         */
        public Activity getTopActivity() {
            Activity mBaseActivity = null;
            synchronized (mActivitys) {
                final int size = mActivitys.size() - 1;
                if (size < 0) {
                    return null;
                }
                mBaseActivity = mActivitys.get(size);
            }
            return mBaseActivity;
    
        }
    
        /**
         * @return 作用说明 :获取当前最顶部的acitivity 名字
         */
        public String getTopActivityName() {
            Activity mBaseActivity = null;
            synchronized (mActivitys) {
                final int size = mActivitys.size() - 1;
                if (size < 0) {
                    return null;
                }
                mBaseActivity = mActivitys.get(size);
            }
            return mBaseActivity.getClass().getName();
        }
    
        /**
         * 结束所有Activity
         */
        public static void finishAllActivity() {
            if (mActivitys == null) {
                return;
            }
            for (Activity activity : mActivitys) {
                activity.finish();
            }
            mActivitys.clear();
        }
    
        /**
         * 退出应用程序
         */
        public  static void appExit() {
            try {
                LogUtils.e("app exit");
                finishAllActivity();
            } catch (Exception e) {
            }
        }
    
        private void registerActivityListener() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                    @Override
                    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                        /**
                         *  监听到 Activity创建事件 将该 Activity 加入list
                         */
                        pushActivity(activity);
    
                    }
    
                    @Override
                    public void onActivityStarted(Activity activity) {
    
                    }
    
                    @Override
                    public void onActivityResumed(Activity activity) {
    
                    }
    
                    @Override
                    public void onActivityPaused(Activity activity) {
    
                    }
    
                    @Override
                    public void onActivityStopped(Activity activity) {
    
                    }
    
                    @Override
                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    
                    }
    
                    @Override
                    public void onActivityDestroyed(Activity activity) {
                        if (null==mActivitys||mActivitys.isEmpty()){
                            return;
                        }
                        if (mActivitys.contains(activity)){
                            /**
                             *  监听到 Activity销毁事件 将该Activity 从list中移除
                             */
                            popActivity(activity);
                        }
                    }
                });
            }
        }
    
    }
    
    

    下面是运行App时 全局监听 添加或者移除Activity的回调时打下的维护的list中Activity数量的变动日志:

    这里写图片描述

    工程源码:
    点击此处 查看该示例Github工程源码

    其他文章推荐:
    Android网络请求发展简史和RxJava+Retrofit+OkHttp实践
    Android BaseAdapter的极简封装

    相关文章

      网友评论

      • YiiY34:getAppNameFromSub 这个方法用来干嘛的。。。
        极客大白:在我自己的项目中 这个类是放到library Module 中的 有个地方用到了具体应用的名字 所以添加了个抽象方法,你实际不需要知道具体App的名字可以删掉。。。
      • 被咯苏州:您好,您的代码好像有个地方有点纰漏
        @Override
        public void onActivityDestroyed(Activity activity) {
        if (null == mActivitys && mActivitys.isEmpty()) {
        return;
        }
        if (mActivitys.contains(activity)) {
        /**
        * 监听到 Activity销毁事件 将该Activity 从list中移除
        */
        popActivity(activity);
        }
        }
        这里mActivitys = null 会空指针的 您这里应该用 ||
        被咯苏州:@geekkevin 嗯呐
        极客大白:确实是 && 应该改为|| 谢谢指正 已更正
      • 气煞宝宝啦:在清单文件中配置application的name,这里会有问题啊,这是抽象类,可以吗?不知道怎么解决了
        极客大白:@气煞宝宝啦 这个是抽象类 你建一个 具体的实例继承 AbsSuperApplication 配置到manifest中就行了
      • 捡淑:可以 这很终极
      • 72f20cc00e42:这种方案,也叫终极!跟自己管理一样,还得考虑兼容,并无任何先进性,也就算骗骗流量的标题党
        243aeabc0e3b:@懂事长 你吐槽得太到位了
        极客大白:@懂事长 嗯,期待您给一个兼容性好、又先进的解决方案
      • 虞愚yu:低版本怎么兼容?
        极客大白:@虞愚yu 嗯 这个API 只有 14 以上可用 做不到兼容低版本 之前 大部分是在BaseActivity中添加删除Activity 如果有更好的实现方式 也请告诉我
        hackest:@虞愚yu 现在一般都到API14吧。
      • 虞愚yu:收藏 学习
      • NKming:当activity数量比较多的话,那内存消耗会很大吧,我觉得应该加上引用吧,而且还能解决内存泄漏。广播关闭应该也行吧
        极客大白:@NKming Activity destroy 的时候可以在 onActivityDestroyed(Activity activity) 中已经将该Activity 移除了 通常 处于开启状态的Activity 不会太多的 不是所有开启过的Activity 都一直引用的
      • 可恶的地瓜:让application持有activity的引用,不会造成内存泄露么?
        Hilary_Lu:当activity销毁的时候,也从activity管理栈中移除了,不会造成泄漏
      • 5c86e01fae2c:学习一下
      • 英勇青铜5:学习到了。 :+1:
      • 黑马有点白986:谢谢!辛苦了
      • Alex_Cin:哈哈,我也有这个文章,思路是一样的。。。还写了,利用application监听,app处于前台后台,楼主可以看一下
      • 浮华染流年:第一次看见这种方式...
      • 迷惘搬运工:不觉得复杂了吗
        极客大白:@清风哥哥 有更好的实现方案吗 还请赐教

      本文标题:Android Activity 全局管理 终极解决方案

      本文链接:https://www.haomeiwen.com/subject/ixjcsttx.html