为什么需要了解关于Activity的任务栈?
其实最直接的体现就是提高用户交互友好性.
举个栗子
当我们去浏览一个新闻客户端的时候,我们进入了新闻详情页,在这个页面有相隔两条的新闻标题,当我们去点击这个标题的时候进入了新的新闻详情页时,如果我们不加以控制会导致什么现象?它会创建出n个新闻详细页的Activity实例,导致用户在退出的时候需要推出多个新闻详情activity,这点在用户体验上是非常不好的,当然对于我们自身的程序也是非常不好的,不断的去创建新的Activity必定会消耗一定的内存,久而久之,应用程序会越来越卡甚至崩溃
在讲Activity任务栈前,我们应该先知道什么是栈?
简单来说可以把栈比作一个开封的箱子,我们可以往里面塞东西,这里假设塞的东西的底面积和箱子的底面积相同.那么这些东西就具备有从下往上一定的顺序.当我们想要从箱子里面取东西的时候,我们没有办法一下子拿到箱子最底层的的东西,我们只可以拿到最上层的东西,从上往下.
来看下这张图,这里的箱子就是栈,箱子口可以看作是栈的入口与出口,东西代表数据。
栈的特点:具有一定的次序,后进先出【越先放入的东西,越晚出来】

任务栈的优缺点
☆ Android系统是通过Activity栈的形式管理Activity的|Activity是与用户交互的接口
☆ 不在栈的顶端,可能会被系统销毁回收Ps:但一般情况下不会被回收,但系统内存不足时会被回收
优点
1> 程序打开时就创建了一个任务栈,用于存储当前程序的activity.当前程序所有的activity属于一个任务栈
2> 一个任务栈包含了一个activity集合,可以有序的选择哪一个activity和用户进行交互,只有在任务栈栈顶的activity才能跟用户进行交互
3> 任务栈可以移动到后台,并且保留了每一个activity的状态. 并且有序的给用户列出它们的任务, 而且还不丢失它们状态信息.
4> 退出应用程序时,当把所有的任务栈中所有的activity清除出栈时,任务栈会被销毁,程序退出.
缺点
1> 每开启一次页面都会在任务栈中添加一个Activity,而只有任务栈中的Activity全部清除出栈时,任务栈被销毁,程序才会退出,这样就造成了用户体验差,需要点击多次返回才可以把程序退出了
2> 每开启一次页面都会在任务栈中添加一个Activity还会造成数据冗余重复数据太多,会导致内存溢出的问题(OOM)
四种状态
Active:Activity处于栈顶,可见,可交互
Paused:可见,但不可交互
Stopped:不可见
Killed:系统回收
四种启动模式
Standard<标准启动模式> singleTop<栈顶启动模式> singleTask<栈内复用启动模式> singleInstance<单实例启动模式>
Standard<标准启动模式>
是默认的启动模式
每次启动一个Activity都重写一个新的实例
Activity的onCreate() onStart() onResume() 方法
singleTop<栈顶启动模式>
1.当前栈中已有该Activity的实例,并且该实例位于栈顶时

有该Activity的实例,并且该实例位于栈顶时
2.当前栈中已有该Activity实例,但实例不在栈顶时

有该Activity实例,但实例不在栈顶时
3.当前栈中不存在该Activity实例(与standard一样)
standard与SingleTop一样,都是在原来的任务栈中新建一个Activity实例,而不会开启一个新的任务栈.
应用场景
IM对话框,新闻客户端推送
SingleTask<栈内复用启动模式>
使用SingleTask时应知道
1> 首先会根据<taskfinity>去寻找当前是否存在一个对应名字的任务栈
2> 如果不存在,则会创建一个新的Task
3> 如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例
1.当需要启动的Activity实例不在栈顶时,使用SingleTask启动,直接置为栈顶,并销毁其他的Activity实例

使用SingleTask启动
应用场景
应用主界面
SingleInstace<单实例启动模式>
使用SingleInstace时应知道
1> 以SingleInstance模式启动的Activity具有全局唯一性
2> 如果在启动这样的Activity时已经存在了一个实例
3> 以SingleInstance模式启动的Activity具有独占性

SingleInstace<单实例启动模式>
应用场景
呼叫来电
自定义任务栈
1.自己维护一个activity的列表
2.每创建一个activity就往这个列表里,增添当前的activity
3.每退出一个activity就finish,并且remove掉当前的activity,
4若要一次性退出activity,那么就遍历一下列表,执行3操作。
上代码辽~~
新建一个类,ActivityManager,代码如下
public static List<Activity> list = new ArrayList<Activity>();
public static void addActivity(Activity activity){
list.add(activity);
}
public static void removeActivity(Activity activity){
list.remove(activity);
}
public static void finish(){
for (Activity activity : list) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("BaseActivity", getClass().getSimpleName()); //得当当前类的名称
//--------------在“Acitivty最佳实践1”新增代码-----------------------------
ActivityManager.addActivity(this);
//-------------------------------------------
}
//--------------在“Acitivty最佳实践1”新增代码-----------------------------
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
ActivityManager.removeActivity(this);
}
//-----------------------------------------------------------------------
public void actionStart(Context context,Class<?> className){
Intent intent = new Intent(context, className);
startActivity(intent);
}
然后在每一个Activity中再添加一个按钮方便测试,UI如下:

以MainActivity为例,代码如下
public class MainActivity extends BaseActivity {
private Button btnMain;
//--------------在“Acitivty最佳实践1”新增代码-----------------------------
private Button btnBack;
//---------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnMain = (Button) findViewById(R.id.activity_main_btn_main);
btnMain.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
actionStart(MainActivity.this,FirstActivtiy.class);
}
});
//--------------在“Acitivty最佳实践1”新增代码-----------------------------
btnBack = (Button) findViewById(R.id.activity_main_btn_back);
btnBack.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ActivityManager.finish();
}
});
//---------------------------------------------------------------------
}
}
这样就完成了我们自定义任务栈的操作了