• Android Activity:四种启动模式,Intent Flags和任务栈


    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。那各个页面跳转关系如何决定呢?如果启动了顺序启动了ABCD的Activiy,如何从D调回到B呢?下面讲述一下Acitivity的四种启动模式。讲解启动模式之前,有必要先讲解一下“任务栈”的概念;

    任务栈

    每个应用都有至少一个任务栈,是用来存放Activity的,功能类似于函数调用的栈,先后顺序代表了Activity的出现顺序;比如Activity1-->Activity2-->Activity3,则任务栈为:

    启动模式:启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的标签的android:launchMode属性设置;

    四种启动模式:

    (1)standard:每次激活Activity时(startActivity),都创建Activity实例,并放入任务栈;这个是系统默认的启动模式;

    (2)singleTop:如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。

    在每次使用新的Activity时会自动检测栈顶的当前Activity是否是需要引用的Activity,如果是则直接引用此Activity,而不会创建新的Activity;当它不需要创建新的Activity对象时,它会调用onNewIntent()方法。

    (3)singleTask:如果要激活的那个Activity在任务栈中存在该实例,则不需要创建,只需要把此Activity放入栈顶,并把该Activity以上的Activity实例都pop(弹出销毁);这个模式可以用来退出整个应用。将主Activity设为SingTask模式,然后在要退出的Activity中转到主Activity,然后重写主Activity的onNewIntent函数,并在函数中加上一句finish。(因为Activity不创建,所以不会进入onCreate函数,只会进入onNewIntent函数)。

    (4)singleInstance:如果应用1的任务栈中创建了MainActivity实例,如果应用2也要激活MainActivity,则不需要创建,两应用共享该Activity实例;

    此启动模式和我们使用的浏览器工作原理类似,我们都知道在多个程序中访问浏览器时,如果当前浏览器没有打开,则打开浏览器,否则会在当前打开的浏览器中访问。此模式会节省大量的系统资源,因为他能保证要请求的Activity对象在当前的栈中只存在一个。

    以上就是Activity的四种启动模式,那标题的Intent Flags又是什么鬼?

    Flags: 表示Intent的标志位,常用于Activity的场景中,它和Activity的启动模式有着密切的联系。

    下面列举的是和本文主题相关的Flags属性:

    Intent.FLAG_ACTIVITY_NEW_TASK (默认)

    默认的跳转类型,它会重新创建一个新的Activity

    FLAG_ACTIVITY_SINGLE_TOP

    这个FLAG就相当于启动模式中的singletop,例如:原来栈中结构是A B C D,在D中启动D,栈中的情况还是A,B,C,D。singleTask不一样的

    FLAG_ACTIVITY_CLEAR_TOP

    这个FLAG有点像启动模式中的SingleTask,这种FLAG启动的Activity会把要启动的Activity之上的Activity全部弹出栈空间。例如:原来栈中的结构是A B C D ,从D中跳转到B,栈中的结构就变为了A B了。但是和SingleTask不一样的是,FLAG_ACTIVITY_CLEAR_TOP会把他上面的弹出,但是自身也销毁,然后重新创建个新对象。而SingleTask不会重新创建新对象,就是不会触发onCreate,只会触发onNewIntent。

    FLAG_ACTIVITY_NO_USER_ACTION

    onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而要退到background时使用。比如,在用户按下Home键,它将被调用。比如有电话进来(不属于用户的选择),它就不会被调用。

    那么系统如何区分让当前activity退到background时使用是用户的选择?

    它是根据促使当前activity退到background的那个新启动的Activity的Intent里是否有FLAG_ACTIVITY_NO_USER_ACTION来确定的。

    注意:调用finish()使该activity销毁时不会调用该函数

    FLAG_ACTIVITY_NO_HISTORY

    意思就是说用这个FLAG启动的Activity,一旦退出,它不会存在于栈中,比方说!原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。

    注意:当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

    如果你对该内容感兴趣,可加入Q群187253654讨论,关注【代码零件】网站或微信公众号

     
  • 相关阅读:
    mysql数据库基本类型
    常用辅助类【转】
    Java 并发笔记】并发机制底层实现整理[转发]
    关于PROPAGATION_NESTED的理解
    线程数设置
    c# Expression 扩展[转]
    Net定时器 【转载】
    【转】高可用设计-58沈剑
    【转】委托的三种调用示例(同步调用 异步调用 异步回调)
    [coursera OA] acme match
  • 原文地址:https://www.cnblogs.com/rockmilk/p/5249988.html
Copyright © 2020-2023  润新知