萌新Android笔记----Activity的启动模式

Activity的启动模式

2020 3 18,天气晴,是个巩固基础摸鱼的好日子,于是萌新兴冲冲写个二次元老婆能来回显示的app,但发现越运行越卡啊。这就涉及到了activity的启动模式问题。

Android的栈

我们首先要知道的是activity是“后进先出”的栈结构,通俗点讲就像羽毛球筒,你想拿到下面的羽毛球就要先拿掉上面那几个。
真要说的话。栈这玩意都得从一个叫TaskAffinity的参数说起,这个参数表示一个activity所需要的栈名,默认情况下是应用的包名,当然我们也可以单独指定。此外,任务栈分为前台任务栈和后台任务栈,后台任务栈的activity处于暂停状态,用户可以通过切换再次调到前台。
但这只是一般情况,特殊情况常常有,毕竟你永远不知道用户能想出多少方法来整你的程序(辛勤的ARK玩家),当TaskAffinity和allTaskReparenting(这玩意在AndroidMenifest设置,作用是允许activity被不同task调用)结合时,会产生特殊效果。举个例子,appA启动appB的一个activityC,且该activityC的allTaskReparenting属性为true,能用,但等B打开后C会直接从A的栈中跑回B的栈(假面骑士Exaid里给父亲献上的月球一击大概就是如此吧。。。父慈子孝)。真正的原因出在allowTaskReparenting上,因为他被设置为true,所以A能用C,但B启动后,系统发现C真正想要的任务栈被创建,就把C移过来了。

简单了解下activity的任务栈后(想摸鱼),我们就可以对启动模式下刀了。activity的默认启动模式是standard,在这个模式下,多次启动同个activity,android会重复创建多个实例。听上去就呆呆的。。不考虑启动模式就开始设计app只会吃力不讨好,萌新刚接触android那会(现在也是)经常犯这种dio时停搬波波–白费劲的错误。目前android共有standard,singleTop,singleTask和singleInstance这四种启动模式。大家都是萌新,一一看过去吧。

  1. standard
    标准模式(默认),无论实例是否已经存在,每次启动activity必定重新创建一个有完整生命周期的实例,会调用onCreate,onStart,onResume方法。值得一提的是standard模式下,一个任务栈可以有多个实例,而每个实例也可以属于不同的任务栈。因此在该模式下,谁启动了这个activity,那这个activity就运行在启动它的那个activity所在的栈中。此外如果我们用ApplicationContext去启动standard模式的activity就会报错,因为非Activity类型的Context没有所谓的任务栈(ApplicationContext是整个应用的上下文,Context是一个activity的上下文)。解决方法是为要启动的activity指定FLAG_ACTIVITY_NEW_TASK标记位,以singleTask模式启动

  2. singleTop
    栈顶复用模式。在这个模式下如果新activity已经位于栈顶,那么activity就不会被重新创建,同时onNewIntent方法会被回调,我们可以通过此方法的参数获取当前请求的信息,而activity的onCreate,onStart方法不会被调用。如果不在栈顶,该模式和standard一样。。。没啥区别。

  3. singleTask
    这个模式下,只要activity在一个栈中存在,那么多次启动此activity都不会重新创建实例。而且同singleTop,系统会回调onNewIntent。简单点讲就是系统收到singleTask模式的activity请求后回去找是否存在A想要的任务栈(Taskffinity),如果不存在就新建一个,如果存在,就看看栈里有没有A,没的话实例化A放在栈顶,有的话把A调到栈顶同时调用onNewIntent方法。

  4. singleInstance
    这玩意和sngleTask差不多,拥有singleTask所有特性,特点就是该模式下的activity只能独立位于一个任务栈中。就是说A启动后,系统为它单独新建一个任务栈,栈里只有他。后续的请求不会创建新的A,除非这个栈被销毁。

    启动模式讲这么多,那我们萌新该怎么为activity指定启动模式呢?
    方法有两种:
    	1:通过AndroidMenifest为activity指定启动模式。如下
    			**android:launchMode="singleTask"**
    	2:通过在Intent中设置标志位来为Activity指定启动模式。如下
    			**Intent intent = new Intent();
    			intent.setClass(MainActivity.this, SecondActivity.class);
    			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    			startActivity(intent);**
    

    优先级上通过Intent指定的优先级高于AndroidMenifest指定,两者同时存在时,以第二种方式为准。

最后来聊聊flags,所谓的标记位,这些标记位作用很多,有的可以设定activity的启动模式,有的可以影响activity的运行状态。。上面的FLAG_ACTIVITY_NEW_TASK就是一个标记位,用来指定singleTask启动模式,效果和在XML中指定该启动模式相同。以此类推,查文档时不要停下来啊!!!

  1. 萌新心得

    总结:activity的启动模式花样很多,如果能掌握的话能很好地提高代码观赏性,同时拓展功能的可能性。学习启动模式的要点在于模式和栈的关系,比如说singleTask认准TaskAffinity栈啊先出后进啊栈里没acitivity就销毁他啊等等。打游戏王魔法卡还分场景瞬发装备永续通常呢(新大师看不懂了)。。编程不比打牌王难?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值