Activity任务栈和启动模式

一、Activity任务栈
在Android中,系统用Task Stack结构来存储和管理启动的Activity对象。
一个应用启动,系统就会为其创建一个对应的Task Stack来存储并管理该应用的Activity对象
只有最上面的任务栈的栈顶的Activity才能显示在窗口中
在这里插入图片描述
栈的特点就是:先进后出
二、Activity启动模式
在Android中,启动一个Activity有时需要创建一个新的对象,有时需要复用已有的对象。
Activity的四种LanchMode
①standard:标准模式、默认模式
含义:每次启动一个Activity就会创建一个新的实例。
注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈。
生命周期:每次被创建的实例Activity 的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。
应用场景:应用与大多数的Activity
举例
此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为Standard 模式。若在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。结果是还有一个C Activity进入栈中,成为栈顶。
在这里插入图片描述
②singleTop:栈顶复用模式
含义:分两种处理情况:需要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。
应用场景:假设你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存!
举例
此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为SingleTop 模式。情况一:在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。
结果是直接复用栈顶的C Activity。
情况二:在C Activity中加入点击事件,须要跳转到还有一个A Activity。结果是创建一个新的Activity入栈。成为栈顶。
在这里插入图片描述
③singleTask:栈内复用模式
含义:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法
应用场景:保持我们应用开启后仅仅有一个Activity的实例。最典型的样例就是应用中展示的主页(Home页)。
假设用户在主页跳转到其他页面,运行多次操作后想返回到主页。
举例
此时Activity 栈中以此有A、B、C三个Activity。此时C处于栈顶,启动模式为SingleTask 模式。
情况一:在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。结果是直接用栈顶的C Activity。情况二:在C Activity中加入点击事件,须要跳转到还有一个A Activity。
结果是将A Activity上面的B、C所有销毁,使A Activity成为栈顶。
在这里插入图片描述

这里写图片描写叙述
④singleInstance:全局单例模式
含义:是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
应用场景:这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。
这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。
举例
三、启动模式的使用方式
(1)在 Manifest.xml中指定Activity启动模式一种静态的指定方法,在Manifest.xml文件里声明Activity的同一时候指定它的启动模式,这样在代码中跳转时会依照指定的模式来创建Activity。样例例如以下:

    <activity android:name="..activity.MultiportActivity" android:launchMode="singleTask"/>

启动Activity时。在Intent中指定启动模式去创建Activity
(2)一种动态的启动模式,在new 一个Intent后,通过Intent的addFlags方法去动态指定一个启动模式。样例例如以下:

   Intent intent = new Intent();
       intent.setClass(context, MainActivity.class);
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       context.startActivity(intent);

注意:以上两种方式都能够为Activity指定启动模式,可是二者还是有差别的。
优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。
限定范围:第一种方式无法为Activity直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,另外一种方式无法为Activity指定 singleInstance 模式。
①FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式。
②FLAG_ACTIVITY_NEW_TASK :对应singleTask模式。
四、复用Activity时生命周期的回调以及Activity跳转时携带页面参数的问题
由于当一个Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再次运行。onCreate方法仅仅会在第一次创建Activity时被运行。

而一般onCreate方法中会进行该页面的数据初始化、UI初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题,若页面展示的数据就是通过getInten() 方法来获取,那么问题就会出现:getInten()获取的一直都是老数据,根本无法接收跳转时传送的新数据!

以下,通过一个样例来具体解释:

Manifest.xml
       <activity
           android:name=".activity.FirstActivity"
           android:launchMode="singleTop"
           android:screenOrientation="portrait" />

public class CourseDetailActivity extends BaseActivity{
  ......
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_course_detail_layout);
        initData();
        initView();
    }

   //初始化数据
    private void initData() {
        Intent intent = getIntent();
        mCourseID = intent.getStringExtra(COURSE_ID);
    }

    //初始化UI
    private void initView() {
    ......
    }
    ......
}

以上代码中的FirstActivity在配置文件里设置了启动模式是SingleTop模式,依据上面启动模式的介绍可得知,当FirstActivity处于栈顶时。再次跳转页面到FirstActivity时会直接复用原有的Activity,并且此页面须要展示的数据是从getIntent()方法得来,可是initData()方法不会再次被调用,此时页面就无法显示新的数据。

当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调 onNewIntent(Intent intent)方法。此方法会传入最新的intent,这样我们就能够解决上述问题。这里建议的方法是又一次去setIntent。然后又一次去初始化数据和UI。代码例如以下所看到的:

   /*
   * 复用Activity时的生命周期回调
   */
       @Override
       protected void onNewIntent(Intent intent) {
           super.onNewIntent(intent);
           setIntent(intent);
           initData();
           initView();
       }

这样,在一个页面中能够反复跳转并显示不同的内容。
五、Activity的Flags
标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比方 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_SINGLE_TOP 等。它还能够影响Activity 的运行状态 ,比方 FLAG_ACTIVITY_CLEAN_TOP 和 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 等。

  1. FLAG_ACTIVITY_NEW_TASK
    作用是为Activity指定 “SingleTask”启动模式。跟在AndroidMainfest.xml指定效果同样。
  2. FLAG_ACTIVITY_SINGLE_TOP
    作用是为Activity指定 “SingleTop”启动模式,跟在AndroidMainfest.xml指定效果同样。
  3. FLAG_ACTIVITY_CLEAN_TOP
    具有此标记位的Activity,启动时会将与该Activity在同一任务栈的其他Activity出栈。一般与SingleTask启动模式一起出现。它会完毕SingleTask的作用。但事实上SingleTask启动模式默认具有此标记位的作用
    4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    具有此标记位的Activity不会出如今历史Activity的列表中,使用场景:当某些情况下我们不希望用户通过历史列表回到Activity时,此标记位便体现了它的效果。它等同于在xml中指定Activity的属性:
    android:excludeFromRecents=“trure”
    文章参考图解四种启动模式 及 实际应用场景解说
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值