Activity 任务栈以及自定义任务栈使用

为什么需要了解关于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();

            }

        }
}

然后在BaseActivity中做如下更改!

@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();

            }

        });

        //---------------------------------------------------------------------

    }

}

这样就完成了我们自定义任务栈的操作了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容