activity管理栈,归整合优

作者: Jafir | 来源:发表于2016-11-02 17:51 被阅读1304次

废话不多说,就是网上学习搜罗了一圈儿,然后加上自己使用过的,总结一个出来。个人认为比较全面了,如果还有需求,留言,我们继续改造。

直接上代码,伸手党可以拿走了。

package com.jafir.qingning.app.manager;

import android.app.Activity;
import android.util.Log;

import java.util.Iterator;
import java.util.Stack;

/**
 * Created by jafir on 16/3/1.
 */
public class ActivityManager {

    private static Stack<Activity> activityStack;
    private Stack<Activity> deleteStack = new Stack<>();
    private static ActivityManager instance;

    private ActivityManager() {
    }

    public static synchronized ActivityManager getInstance() {
        if (instance == null) {
            instance = new ActivityManager();
             if (activityStack == null) {
                    activityStack = new Stack<>();
              }
        }
        return instance;
    }

    public Stack<Activity> getActivityStack() {
        return activityStack;
    }

    /**
     * 返回当前栈顶的activity
     *
     * @return
     */
    public Activity currentActivity() {
        if (activityStack.size() == 0) {
            return null;
        }
        Activity activity = activityStack.lastElement();
        return activity;
    }

    /**
     * 栈内是否包含此activity
     *
     * @param cls
     * @return
     */
    public boolean isContains(Class<?> cls) {
        for (Activity activity : activityStack) {
            if (activity.getClass().equals(cls)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 栈内是否包含此activity
     *
     * @param a
     * @return
     */
    public boolean isContains(Activity a) {
        for (Activity activity : activityStack) {
            if (activity.equals(a)) {
                return true;
            }
        }
        return false;
    }

    /**
     * activity入栈
     * 一般在baseActivity的onCreate里面加入
     *
     * @param activity
     */
    public void pushActivity(Activity activity) {
        activityStack.add(activity);
    }


    /**
     * 移除栈顶第一个activity
     */
    public void popTopActivity() {
        Activity activity = activityStack.lastElement();
        if (activity != null && !activity.isFinishing()) {
            activity.finish();
        }
    }

    /**
     * activity出栈
     * 一般在baseActivity的onDestroy里面加入
     */
    public void popActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
        }
        if (!activity.isFinishing()) {
            activity.finish();
            activity = null;
        }
    }

    /**
     * activity出栈
     * 一般在baseActivity的onDestroy里面加入
     */
    public void popActivity(Class<?> cls) {
        Activity deleteActivity = null;
        for (Activity activity : activityStack) {
            if (activity.getClass().equals(cls) && !activity.isFinishing()) {
                deleteActivity = activity;
                activity.finish();
            }
        }
        activityStack.remove(deleteActivity);
    }


    /**
     * 从栈顶往下移除 直到cls这个activity为止
     * 如: 现有ABCD popAllActivityUntillOne(B.class)
     * 则: 还有AB存在
     * <p>
     * 注意此方法 会把自身也finish掉
     *
     * @param cls
     */
    public void popAllActivityUntillOne(Class cls) {
        while (true) {
            Activity activity = currentActivity();
            if (activity == null) {
                break;
            }
            if (activity.getClass().equals(cls)) {
                break;
            }
            popActivity(activity);
        }
    }

    /**
     * 所有的栈元素 除了 cls的留下 其他全部移除
     * 如: 现有ABCD popAllActivityUntillOne(B.class)
     * 则: 只有B存在
     * 注意此方法 会把自身也finish掉
     */
    public void popAllActivityExceptOne(Class cls) {
        //第一种  ConcurrentModificationException
//        for (Activity activity : activityStack) {
//            if (!activity.getClass().equals(cls) && !activity.isFinishing()) {
//                activityStack.remove(activity);
//                activity.finish();
//            }
//        }

        // 第四种 ConcurrentModificationException
//        for (int i = 0; i < ; i++) {

        // 第三种 可行
        Iterator iterator = activityStack.iterator();
        while (iterator.hasNext()) {
            Activity activity = (Activity) iterator.next();
            if (!activity.getClass().equals(cls) && !activity.isFinishing()) {
//                activityStack.remove(activity);
//               注意这里必须要用iterator的remove 上面的则错误
                iterator.remove();
                activity.finish();
            }
        }

        //第四种 可行 稍显复杂
//        for (Activity activity : activityStack) {
//            if (!activity.getClass().equals(cls) && !activity.isFinishing()) {
//                deleteStack.add(activity);
//                activity.finish();
//            }
//        }
//        /**
//         * 这里进行了特殊处理,如果直接在循环里面remove会报
//         * concurrentmodificationexception 错误
//         * 所以,这里用另一个栈加入进去,统一移除
//         */
//        activityStack.removeAll(deleteStack);
//        deleteStack.clear();
        Log.d("debug", "dsfsaf size+:" + activityStack.size());
    }

    /**
     * 移除所有的activity
     * 退出应用的时候可以调用
     * (非杀死进程)
     */
    public void popAllActivity() {
        for (int i = 0; i < activityStack.size(); i++) {
            if (null != activityStack.get(i) && !activityStack.get(i).isFinishing()) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }


    /**
     * 获得现在栈内还有多少activity
     *
     * @return
     */
    public int getCount() {
        if (activityStack != null) {
            return activityStack.size();
        }
        return 0;
    }
}

没啥好说的,就谈几个需要注意的地方,和我遇到的问题。

注意:

  • 这里在使用stack.lastElement的时候最好加一个判空
   public Activity currentActivity() {
       if (activityStack.size() == 0) {
           return null;
       }
       Activity activity = activityStack.lastElement();
       return activity;
   }
  • 看** popAllActivityUntillOne popAllActivityExceptOne**
  • 尤其是popAllActivityExceptOne,在这里之前遇到了坑。
  • 遇到了ConcurrentModificationException的异常,之前一直以为iterator不可以删除,但是,是我错了,看代码里面吧。
    ~~activityStack.remove(activity);~~
//               注意这里必须要用iterator的remove 上面的则错误
    iterator.remove();
  • 那几种方法我都试过了,就选第二种iterator用吧。

Ps:其他用这个方式解决finish需求有点老了,也有一些弊端,可能出现内存泄露什么的,如果这个还可以改进的话,快点留言!我渴望知道你的答案。
通过和其他人交流,觉得event发送消息去让activity自身finish也是一种比较好的方式,更安全。

方法我简单说一下:
baseActivity里面,加入onMainEvent(event),event最好加入一个标识,就是你所要finish的activity的名字吧,然后判断一下,相等就finish,就这么简单。

相关文章

网友评论

    本文标题:activity管理栈,归整合优

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