2021-11-04Android的四种启动模式(LaunchMode)

1.为什么要使用启动模式?

在我们的Android开发之中,当我们多次启动同一个Activity的时候,系统汇创将多个重复的实例,将他们放到任务栈之中。当我们点击返回键的时候,这些Activity实例又将从任务栈中一一移除,遵循栈“后进先出”的原则。

2.启动模式的分类

1.默认模式 Standard

说明: Android创建Activity时的默认模式,假设没有为Activity设置启动模式的话,默觉得标准模式。每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。

生命周期:如上所看到的,每次被创建的实例Activity 的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。

  • 在Manifest中配置:对于标准模式,android:launchMode=”standard”可以不写,因为默认就是standard模式。
<activity
    android:name=".StandardActivity"
    android:launchMode="standard" >
</activity>
  • 启动Activity的时候。在Intent中指定启动模式去创建Activity

通过Intent的addFlags方法去动态的指定一个启动模式。

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

这时我们不需要去设置启动Flags,默认就是standard启动

2.SingleTop 栈顶复用模式

说明:分两种处理情况:须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。

生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。

  • 在 Manifest.xml中指定Activity启动模式
        <activity android:name="..activity.MultiportActivity" android:launchMode="singleTop"/>
  • 启动Activity时。在Intent中指定启动模式去创建Activity
        Intent intent = new Intent();
        intent.setClass(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        context.startActivity(intent);

这里的FLAG_ACTIVITY_SINGLE_TOP就是我们设置的标记位,作用就是为Activity指定“singleTop”启动模式

3.栈内复用模式

说明:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。

生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法

  • 在Manifest中配置:
        <activity android:name="..activity.MultiportActivity" android:launchMode="singleTask"/>
  • 启动Activity时。在Intent中指定启动模式去创建Activity
        Intent intent = new Intent();
        intent.setClass(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);

这里的FLAG_ACTIVITY_NEW_TASK就是我们设置的标记位,作用就是将Activity的启动模式设置为singleTask

4.SingleInstance:单例模式的实现

  • 在Manifest中配置:
        <activity android:name="..activity.MultiportActivity" android:launchMode="singleTask"/>

这里的SingleInstance才是四种启动模式中的重点,它具备所有的SingleTask的特点,就是一种加强的singleTask。但是和别的四种启动模式不同的是:这种启动模式会单独的创建一个任务栈,上面的三种启动模式都是存在于同一个任务栈之中,而这种的模式存在于另一个任务栈之中。这样的存在模式使用的时候可能存在这一些问题,下面我们在进行分析。
我们定义了ActivityA和ActivitySecond两个界面
当我们启动ActivityA后:

image.png

点击按钮进入ActivitySecond
image.png


当我们退出去之后暂时退出去后,重新进入后返回的结果:
image.png

这里的原因是:当我们重新进入的时候,我们会重新的在主任务栈进行查找,若没有就会进行创建,但是我们的SecondActivity在另外的一个任务栈之中,这样当我们使用了home键暂时的退出程序后再进入,此时会调用主任务栈中栈顶Activity的onRestart,不会调
用SecondActivity的onRestart。

想着查询一些资料找到解决的办法,但是后来发现其实这个问题根本不需要解决。

因为我们此时根本不需要将我们的launchMode设置为singleInstance,这样的启动模式只会运用在一些特定的需要独立栈操作的应用上面。比如说:呼叫来电界面。当我们正在A应用中看视频的时候,接收到来电,点击进入到来电详情界面,当我们点击返回之后就回到A视频的界面,这样就不会干扰到用户之前的操作。
这个时候我们只会产生一个单独运行的Activity的界面,这个Activiyt会具有全局唯一性,整个系统之中只会存在一个这样的实例;

其实上面的呼叫来电的界面和我们的ActivitySecond界面大同小异,我们的ActivityA就相当于上面的应用A,只不过,当我们退出通话界面的时候,系统会挂起通话界面也就是实现onPause,但是此时通话任务任然的进行,通话界面之中虽然可以可以控制通话的结束,但是两者的生命周期却是没有进行绑定。当我们的通话任务结束的时候才能够对通话界面进行销毁。
这样的功能都是可以在我们的ActivitySecond界面的基础之上进行实现。

3.复用Activity时的生命周期回调

由于当一个Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再次运行。onCreate方法仅仅会在第一次创建Activity时被运行。

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

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() {
    ......
    }
    ......
}

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

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

/*
* 复用Activity时的生命周期回调
*/
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        initData();
        initView();
    }
那么onNewIntent都会在什么情况下调用呢?

前提:ActivityA已经启动过,处于当前应用的Activity堆栈中;

当ActivityA的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法

当ActivityA的LaunchMode为SingleInstance,SingleTask时,如果已经ActivityA已经在堆栈中,那么此时会调用onNewIntent()方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容