对Activity管理(附源码理解)

相信很多刚入行的朋友在开发界面繁多,逻辑复杂的App的时候对Activity的管理很是头疼。尽管论坛上面很多关于Activity管理的资源,但是注释明确清晰(简单易懂)的还是挺少的,所以博主发一下自己对这方面的见解,如有什么有错误的地方,请指出,同时多多包涵,好啦,不说这么多客套话了。Coding time!

下面我附一个网上很实用的一个管理Activity的类文件:

package com.example.lenovo.mproject;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;

import java.util.Stack;

/**
 * Created by wz on 2016/6/23.
 */
public class AppManager {
    // Activity栈
    private static Stack<Activity> activityStack;
    // 单例模式
    private static AppManager instance;

    private AppManager() {
    }

    /**
     * 单一实例
     */
    public static AppManager getAppManager() {
        if (instance == null) {
            instance = new AppManager();
        }
        return instance;
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        if (activityStack == null) {
            activityStack = new Stack<Activity>();
        }
        activityStack.add(activity);
    }

    /**
     * 获取当前Activity(堆栈中最后一个压入的)
     */
    public Activity currentActivity() {
        Activity activity = activityStack.lastElement();
        return activity;
    }

    /**
     * 结束当前Activity(堆栈中最后一个压入的)
     */
    public void finishActivity() {
        Activity activity = activityStack.lastElement();
        finishActivity(activity);
    }

    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity.finish();
            activity = null;
        }
    }

    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls) {
        for (Activity activity : activityStack) {
            if (activity.getClass().equals(cls)) {
                finishActivity(activity);
            }
        }
    }

    /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        for (int i = 0; i < activityStack.size(); i++) {
            if (null != activityStack.get(i)) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }

    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {
        try {
            finishAllActivity();
            ActivityManager activityMgr = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {
        }
    }
}


 
 


一、压入栈中和获取栈顶Activity

/**
 * 添加Activity到堆栈  
     **/  
    public void addActivity(Activity activity) {  
        if (activityStack == null) {  
            activityStack = new Stack<Activity>();  
        }  
        activityStack.add(activity);  
    }  
  
    /** 
     * 获取当前Activity(堆栈中最后一个压入的) 
     */  
    public Activity currentActivity() {  
        Activity activity = activityStack.lastElement();  
        return activity;  
    }

在此之前我们需要Stack这个类,Stack中文翻译是栈的意思,我们知道在默认的标准Activity启动模式中(standard),Activity在栈中遵循先入后出的规则,所以当我们需要灵活

的去管理这些压入栈中的Activity时,需要自己使用单例创建一个专门用于管理Activity的管理类,该工具类中就是使用Stack这个集合去管理集合内的所有Activity,这使我们在需

要管理的Activity类中必须把该类add进这个栈的集合,在获取栈顶的Activity时候(也就是堆栈最后一个压入的或者说是当前的Activity),调用了LastElement法:



 /**
     * Returns the last element in this vector.
     *
     * @return the element at the last position.
     * @throws NoSuchElementException
     *                if this vector is empty.
     * @see #elementAt
     * @see #firstElement
     * @see #size
     */
    @SuppressWarnings("unchecked")
    public synchronized E lastElement() {
        try {
            return (E) elementData[elementCount - 1];
        } catch (IndexOutOfBoundsException e) {
            throw new NoSuchElementException();
        }
    }


<span style="font-size:18px;"><strong> 二、从栈中移除指定Activity
</strong></span><pre name="code" class="java"> /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity.finish();
            activity = null;
        }
    }


 

 

从源码中可以看出,返回了栈集合中最后一个(也就是栈顶或者说是当前的Activity)的元素,elementCount也就是这个压入栈中元素的个数。

我们接着看下去:


   /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity.finish();
            activity = null;
        }
    }
当我们调用结束指定的这个方法时,在该Activity存在或者是未被GC机制回收的情况下该调用该栈集合的remove方法:
   /**
     * Removes the first occurrence, starting at the beginning and moving
     * towards the end, of the specified object from this vector. All elements
     * with an index bigger than the element that gets removed have their index
     * decreased by 1.
     *
     * @param object
     *            the object to remove from this vector.
     * @return {@code true} if the specified object was found, {@code false}
     *         otherwise.
     * @see #removeAllElements
     * @see #removeElementAt
     * @see #size
     */
    @Override
    public boolean remove(Object object) {
        return removeElement(object);
    }

<pre name="code" class="java"> /**
     * Removes the first occurrence, starting at the beginning and moving
     * towards the end, of the specified object from this vector. All elements
     * with an index bigger than the element that gets removed have their index
     * decreased by 1.
     *
     * @param object
     *            the object to remove from this vector.
     * @return {@code true} if the specified object was found, {@code false}
     *         otherwise.
     * @see #removeAllElements
     * @see #removeElementAt
     * @see #size
     */
    public synchronized boolean removeElement(Object object) {
        int index;
        if ((index = indexOf(object, 0)) == -1) {
            return false;
        }
        removeElementAt(index);
        return true;
    }
    /**
     * Searches in this vector for the index of the specified object. The search
     * for the object starts at the beginning and moves towards the end of this
     * vector.
     *
     * @param object
     *            the object to find in this vector.
     * @return the index in this vector of the specified element, -1 if the
     *         element isn't found.
     * @see #contains
     * @see #lastIndexOf(Object)
     * @see #lastIndexOf(Object, int)
     */
    @Override
    public int indexOf(Object object) {
        return indexOf(object, 0);
    }

    /**
     * Searches in this vector for the index of the specified object. The search
     * for the object starts at the specified location and moves towards the end
     * of this vector.
     *
     * @param object
     *            the object to find in this vector.
     * @param location
     *            the index at which to start searching.
     * @return the index in this vector of the specified element, -1 if the
     *         element isn't found.
     * @throws ArrayIndexOutOfBoundsException
     *                if {@code location < 0}.
     * @see #contains
     * @see #lastIndexOf(Object)
     * @see #lastIndexOf(Object, int)
     */
    public synchronized int indexOf(Object object, int location) {
        if (object != null) {
            for (int i = location; i < elementCount; i++) {
                if (object.equals(elementData[i])) {
                    return i;
                }
            }
        } else {
            for (int i = location; i < elementCount; i++) {
                if (elementData[i] == null) {
                    return i;
                }
            }
        }
        return -1;
    }


/**
     * Removes the element found at index position {@code location} from
     * this {@code Vector}. All elements with an index bigger than
     * {@code location} have their index decreased by 1.
     *
     * @param location
     *            the index of the element to remove.
     * @throws ArrayIndexOutOfBoundsException
     *                if {@code location < 0 || location >= size()}.
     * @see #removeElement
     * @see #removeAllElements
     * @see #size
     */
    public synchronized void removeElementAt(int location) {
        if (location >= 0 && location < elementCount) {
            elementCount--;
            int size = elementCount - location;
            if (size > 0) {
                System.arraycopy(elementData, location + 1, elementData,
                        location, size);
            }
            elementData[elementCount] = null;
            modCount++;
        } else {
            throw arrayIndexOutOfBoundsException(location, elementCount);
        }
    }


 从源码看这几个方法在Vector这个类中,而Stack类又是继承的Vector,在移除指定的Activity时候前遍历这个集合获取到指定Activity栈的index,然后通过removeElementAt(int index),这个方法里面有意思的一个方法也就是: 
System.arraycopy(elementData, location + 1, elementData,
                        location, size);

讲真,博主以前也没用过和听说过,经过大概的了解,这里也和大家简单介绍一下:这个方法主要用于对大型集合的复制,因为一般的集合复制需要我们去遍历,当集合过多,对于性能的影响会比较大。这里我们常用的方法是这样:
public static native void arraycopy(Object src, int srcPos,
        Object dst, int dstPos, int length);

 
简单介绍一下该方法:也就是从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。  

回到刚刚的removeElementAt方法中,当栈的集合长度减一等于被移除的下标的时候(也就是栈顶时候),size>0返回false,然后给指定的Activity对象赋NULL值。当指定移除的Activity不是出于栈顶时,size>0返回true,通过arraycopy方法对该栈集合进行重组,把被指定的Activity排在最后一个元素然后一样把该元素赋NULL值。可能会有人疑问,你怎么说集合被重组了??下面我贴出源码的关键代码:

  if (size > 0) {
                System.arraycopy(elementData, location + 1, elementData,
                        location, size);
            }


 
 
 
 

这层判断刚刚我已经说明了:

当指定移除的Activity不是出于栈顶时,size>0返回true 

同时也介绍过arraycopy方法,这里可以看出是复制elementData从下标location+1到下标location+1+size-1给elementData的下标location到下标location+size-1。

上面这段逻辑可能有点绕,但是静下来理一理就好了。

location+1+size-1我们可以进行换算,从上面源码可以看到size=elementCount-location 也就是location+1+size-1 = location+1+elementCount-location-1 = elementCount 这

样看是不是思路清晰一些了。


三、清空堆栈(退出程序)

  /**
     * 结束所有Activity
     */
    public void finishAllActivity() {
        for (int i = 0; i < activityStack.size(); i++) {
            if (null != activityStack.get(i)) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }

    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {
        try {
            finishAllActivity();
            ActivityManager activityMgr = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {
        }
    }



相信很多人都在懊恼程序不能够完全退出的问题,反正博主是遇见过,后来还是解决了。不废话了,看上面的代码可知道是遍历单例出来的管理集合,然后去结束掉所有的Actvitiy,然后清空这个堆栈集合,最后获取到ActivityManager去杀死掉所有的后台进程,最后退出程序,保证退出后所有的后台服务也被销毁。


这次对于源码简单的分析就到这里,希望能够帮助到需要的人,如果有什么错误的地方,希望大家能够指出,我谦虚学习请教。


最后祝大家工作顺利,走上人生巅峰。。

 
 
 
 
 
 
 
 
 
 
 
 






附源码:http://download.csdn.net/detail/u011862733/9568978

 
 
 
 
 
 



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值