Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-03-13:LaunchMode 的应用场景? #4

Open
Moosphan opened this issue Mar 13, 2019 · 23 comments
Open

2019-03-13:LaunchMode 的应用场景? #4

Moosphan opened this issue Mar 13, 2019 · 23 comments

Comments

@Moosphan
Copy link
Owner

No description provided.

@Ssuiyingsen
Copy link

Ssuiyingsen commented Mar 13, 2019

  1. android:launchMode="standard"
    可以存在多个实例,这是默认的启动模式,系统总是会在目标栈中创建新的activity实例。
  2. android:launchMode="singleTop"
    如果这个 activity 实例已经存在目标栈的栈顶,系统会调用这个 activity 中的 onNewIntent() 方法,并传递 intent,而不会创建新的 activity 实例;如果不存在这个 activity 实例或者 activity 实例不在栈顶,则 SingleTopStandard 作用是一样的。
  3. android:launchMode="singleTask"
    不会存在多个实例,如果栈中不存在 activity 实例,系统会在新栈的根部创建一个新的 activity;如果这个 activity 实例已经存在,系统会调用这个 activityonNewIntent() 方法而不会创建新的 activity 实例。
  4. android:launchMode="singleInstance"
    这种启动模式比较特殊,因为它会启用一个新的栈结构,将 Acitvity 放置于这个新的栈结构中,并保证不再有其他 Activity 实例进入,除此之外,SingleInstance 模式和 SingleTask 模式是一样的。

@ADrunkenLiBai
Copy link

指定方式有什么用处呢

@Moosphan
Copy link
Owner Author

Moosphan commented Mar 13, 2019

LaunchMode 有四种,分别为 StandardSingleTopSingleTaskSingleInstance,每种模式的实现原理一楼都做了较详细说明,下面说一下具体使用场景:

  • Standard:
    Standard 模式是系统默认的启动模式,一般我们 app 中大部分页面都是由该模式的页面构成的,比较常见的场景是:社交应用中,点击查看用户A信息->查看用户A粉丝->在粉丝中挑选查看用户B信息->查看用户A粉丝... 这种情况下一般我们需要保留用户操作 Activity 栈的页面所有执行顺序。
  • SingleTop:
    SingleTop 模式一般常见于社交应用中的通知栏行为功能,例如:App 用户收到几条好友请求的推送消息,需要用户点击推送通知进入到请求者个人信息页,将信息页设置为 SingleTop 模式就可以增强复用性。
  • SingleTask:
    SingleTask 模式一般用作应用的首页,例如浏览器主页,用户可能从多个应用启动浏览器,但主界面仅仅启动一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
  • SingleInstance:
    SingleInstance 模式常应用于独立栈操作的应用,如闹钟的提醒页面,当你在A应用中看视频时,闹钟响了,你点击闹钟提醒通知后进入提醒详情页面,然后点击返回就再次回到A的视频页面,这样就不会过多干扰到用户先前的操作了。

@familyyan
Copy link

为什么要有启动模式?
因为在Android中,启动一个Activity有时需要创建一个新的对象,有时需要复用已有的对象
①standard:标准模式、默认模式
含义:每次启动一个Activity就会创建一个新的实例。
注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈。
生命周期:每次被创建的实例Activity 的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。
应用场景:应用与大多数的Activity

②singleTop:栈顶复用模式
含义:分两种处理情况:需要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。
应用场景:假设你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存!

③singleTask:栈内复用模式
含义:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法
应用场景:保持我们应用开启后仅仅有一个Activity的实例。最典型的样例就是应用中展示的主页(Home页)。
假设用户在主页跳转到其他页面,运行多次操作后想返回到主页。

④singleInstance:全局单例模式
含义:是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
应用场景:这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。

@scsfwgy
Copy link

scsfwgy commented Apr 25, 2019

针对singleInstance应用场景说一下,其它都比较好理解。大致可以理解为全局单例,它应该独立于应用的,就是说和整个业务流应该是单独分离的。个人感觉比较常见的应用场景是:类似微信、QQ、微博的第三方授权页面是典型的应用场景。

@RedDargon
Copy link

launchMode即Activity的启动模式 。可以在manifest里面设定 ,一共四种类型:
1.standard 默认状态 ,不管存不存在 只要start 就会创建。
2.singleTop 不存在此界面就会创建,而界面如果处于栈顶 再次start,只会执行onNewIntent 而不是重新开启个新的界面 。
3.singleTask 不存在此界面就会创建,而界面如果在栈中 再次start 会把处于他上面的界面全部扔掉并把他抬到栈顶 并执行onNewIntent。
4.singleInstance start后会为此Activity单独开启一个栈,再次开启会判断此Activity是否存在 存在就会跳到此栈 显示此界面。设置了此启动模式的Activity 必定单例。

大多数界面都会设置singleTop ,主页会设置singleTask 。singleInstance的界面 多为系统界面吧 比如打电话界面。

@hyyaoming
Copy link

singletask模式用的比较多,一般项目首页就可以采用此模式,比如应用中的返回首页按钮。

@yeyueduxing
Copy link

挖下坟,说下对singleInstance的理解。
singleInstance是开启另外一个任务栈的页面,意思可以这样理解,它的作用是打开一个独立场景的页面,这个页面和应用内的其他页面没有连续性的,而是一个独立的。例如,打电话页面,我们在A页面点击一个按钮进入打电话页面C,然后正在通话,在原本A页面打开其他页面B,在我们的操作习惯里面A和B是有关联的,C其实是独立的,我们并不想在正常操作应用的时候又跳到打电话页面去,这个页面是我们打开的,但却是独立开来,和我们的操作流程无关。所以一个新的独立栈也是需要的。

@siren4
Copy link

siren4 commented Aug 12, 2019

singleTask什么时候开启新栈?
当启动的activity的启动模式为singleTask时,会首先检测manifest中的taskAffinity属性,如果taskAffinity存在并且和已有的taskAffinity不同时(默认是包名),则创建新的任务栈,并把目标activity放入其中,否则不会创建新栈。

@wangxuyang518
Copy link

为什么要有启动模式?
因为在Android中,启动一个Activity有时需要创建一个新的对象,有时需要复用已有的对象
①standard:标准模式、默认模式
含义:每次启动一个Activity就会创建一个新的实例。
注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈。
生命周期:每次被创建的实例Activity 的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。
应用场景:应用与大多数的Activity

②singleTop:栈顶复用模式
含义:分两种处理情况:需要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。
应用场景:假设你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存!

③singleTask:栈内复用模式
含义:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。
生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法
应用场景:保持我们应用开启后仅仅有一个Activity的实例。最典型的样例就是应用中展示的主页(Home页)。
假设用户在主页跳转到其他页面,运行多次操作后想返回到主页。

④singleInstance:全局单例模式
含义:是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
应用场景:这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。

launch 程序,你可以看下 系统代码。并不是设置singleInstance,老哥 别误导别人,。不是我看了下源码,还信以为真了

@wangxuyang518
Copy link

newIntent 在lanchMode 设置成SingTop 或者Intent 设置SingTop 的flag,才会再次调用。 通过getIntent得到之前的Intent。通过setIntent设置新的Intent 。

SingleInstance应用场景,我看了系统的launch程序,蓝牙程序并不是设置的SingInstanche。相反百度了一圈,俩个应用之间调起Activity,为了不影响彼此,设置成SingleInstance。这个理由/解释不错

@realshura
Copy link

回答得都太简单了,都没有结合taskAffinity和Flag来回答。

@twfx5
Copy link

twfx5 commented Nov 27, 2019

SingleTask栈内复用模式:
它与SingleTop类似,SingleTop只检查栈顶的Activity,SingleTask则检查是否存在这个任务栈;

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task,当使用SingleTask来启动Activity时:
taskAffinity不同,则会重新创建一个任务栈,然后把Activity放到新任务栈中

taskAffinity不重新指定,则会在原来的任务栈中寻找。如果没有,会在当前的任务栈中创建Activity。如果有则把上面的Activity全部出栈,同时也会调用onNewIntent方法;

@NicoTic
Copy link

NicoTic commented Dec 8, 2019

大佬,有个问题不太明白,比如App 用户在ActivityA界面,此时收到几条好友请求的推送消息,用户点击推送通知进入到ActivityB界面,如果ActivityB用SingleTop模式启动,因为ActivityB并不是在栈顶,那么不是会创建一个新的ActivityB实例吗?用户在ActivityB是不是就会需要两次返回才能退出??

@JesusYoung
Copy link

大佬,有个问题不太明白,比如App 用户在ActivityA界面,此时收到几条好友请求的推送消息,用户点击推送通知进入到ActivityB界面,如果ActivityB用SingleTop模式启动,因为ActivityB并不是在栈顶,那么不是会创建一个新的ActivityB实例吗?用户在ActivityB是不是就会需要两次返回才能退出??

SingleTop为栈顶复用,当ActivityB不在栈顶时,会重新创建一个新的ActivityB1,返回时ActivityB1销毁,回到ActivityA,如果此时正在ActivityB界面,又弹出通知消息,点击消息时,要就不会在创建新的ActivityB,而是直接复用目前栈顶的ActivityB,实现了栈顶复用。

@gs666
Copy link

gs666 commented Jun 2, 2020

如果入口activity设置为“SingleTask”,回到主页再进入应用,会打开入口类,不会保存原来的状态。

@zhouyueyuedsf
Copy link

这个东西自己没用过 是比较难理解的。另外这里面感觉比较乱很有可能是android对这块没有设计好。

@YuxiangZhu
Copy link

https://www.bilibili.com/video/BV1CA41177Se?t=237
朱凯大神这个大制作,讲的就很牛逼了

@mlduan
Copy link

mlduan commented Jul 5, 2021

https://www.bilibili.com/video/BV1CA41177Se?t=237
朱凯大神这个大制作,讲的就很牛逼了

讲的是真的好...感觉看一遍都不够...要反复观摩

@mlinqirong
Copy link

mlinqirong commented Dec 13, 2021

activity的启动模式有四种standard(默认),singleTask,singleTop,singleInstance
standard:启动activity都会在栈中创建一个实例
singleTask:启动activity时 当任务栈中已经有实例时,使用任务栈中的实例,当没有实例时才会去创建实例
singleTop:启动activity时,当任务栈顶已经有实例时,使用任务栈顶中的实例,没有实例才去创建实例
singleInstance:启动activity时,创建一个新的栈和实例,并保证不会有其他实例 这是一个单例

@spxcc
Copy link

spxcc commented Apr 17, 2022

设置了singleTask为启动模式的Activity,它在启动的时候,会先在系统中查找是否存在属性值taskAffinity等于它自己的任务栈存在,

  • 如果不存在:就在新任务栈中启动

  • 如果存在:则找到该任务栈,查找该任务栈中是否存在该Activitcly实例,

    • 如果存在实例:则将它上面的Activity实例都出栈,然后回调启动的Activity实例的onNewIntent方法,另外生命周期方法执行顺序为onPause(当前activity) -> onNewIntent ->onRestart->onStart->onResume->出栈的activity依次从低到高执行onStop、onDestroy;
    • 如果不存在该实例: 则新建Activity,并入栈。

因此,如果我们想要设置了启动模式为singleTask的Activity在新的任务栈中启动,就要为它设置一个独立的taskAffinity属性值。另外,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去

@luckilyyg
Copy link

luckilyyg commented Apr 17, 2022 via email

@b1tb1t
Copy link

b1tb1t commented Jan 24, 2024

补充个新的,第五种android12以上才有效果
singleInstancePerTask

当目标栈的底部为当前activity则其栈与生命周期的变化与singleTask模式一样。
当目标栈不存在此acitivty时其栈与生命周期的变化与singleInstance模式一样。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests