这是我参与「第四届青训营 」笔记创作活动的第4天
活动的启动模式
在Android中,Activity 的启动模式有5种,我们大多数开发中,很少根据具体的场景去设定Activity的启动模式,其实启动模式可以在解决某些场景问题的时候,让我们更简单的去解决到问题
一、standard-标准模式
描述:Activity默认都是这个模式,每次创建Activity都会创建一个新的实例
注意点: 1)在我们创建一个 Activity 类的时候,不在 AndroidManifest.xml 的 Activity 中 显示指定android:launchMode 的情况下,都是这种模式;
2)这种模式下(我们假设有一个 YoungActivity),哪个 Activity 启动了YoungActivity,那么YoungActivity就运行哪个 Activity 所属的栈中;
3)在非Acitivty的 context(例如:getApplicationContext()) 去启动一个当前模式的 Activity,会引发下面的异常
4)Activity12之前,在Root Activity点击返回键,应用返回桌面,Activity会执行onDestory方法,在Android12开始,则不会执行onDestory方法,也就是说数据保留了
android.util.AndroidRuntimeException: Calling startActivity() from outside of
an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this
really what you want?
之所以会出现上面的异常,是因为在非activity的context不存在activity的任务栈,而新启动的Activity,需要去和启动它的activity在 同一个任务栈中,所以无法启动 Activity,也就是上面的异常。
解决的方式 方式1:按照异常的提示,跳转的时候,设置一个新的任务栈
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //设置新的任务栈
getApplicationContext().startActivity(intent);
方式2:可以把需要启动的 Activity 的模式设置为 singleTask
二、singleTop-栈顶复用模式
应用场景:Activity被启动起来的渠道多,适合多应用开启调用的Activity,通过这种设置可以避免已经创建过的Activity被重复创建,可以提供共享的,例如:相机、通知栏点击后需要启动一个活动页(该页面也许已经存在栈内)
再比如应用现在就处于一个Activity,而现在弹出一条通知,点击这条通知可以跳转到当前的Activity,在standard模式下就会直接创建一个新的Activity放在栈顶,singleTop模式就是直接复用当前的Activity
描述:这种模式只有当被启动的Activity(例如:YoungActivity)已经在栈顶了,那么其他地方调用起它,那么它是不会重新创建的,但是如果当前处于栈顶的 Activity 不是 YoungActivity,那么它是会被创建的
注意点: 1)如果新的activity已经处于任务栈的栈顶,那么这个activity不会创建新的activity实例,同时它的onNewIntent()会被调用, 通过此方法的参数我们可以取出当前请求的信息。如果这个栈顶activity被启动,这个activity的onCreate()、onStart()方法 就不会被执行,因为这个活动没有发生改变
三、singleTask-栈内复用模式
应用场景:APP首页/主页
描述: 1)在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop 一样,系统也会回调其 onNewIntent()方法;
注意点: 1)当被启动的Activity(例如:YoungActivity)存在栈中,但是非栈顶,其他Activity去启动它的时候,会把YoungActivity之上的所有Activity全部退出栈
四、singleInstance-单实例模式
应用场景:APP首页/主页/呼叫来电界面
描述:
1)新开一个任务栈,该栈内只存放当前实例,但是即使是在不同任务张,也不会出现例如小程序那种情况多任务情况,要实现那种效果,还需要将Activity的taskAffinity设置为不同。
2)此模式是singleTask的加强模式,具有singleTask的全部特性,并且是这种模式启动的activity只能单独的位于一个任务栈中。如果继续启动这个activity,不回去继续创建新的activity,也不会重新创建任务栈,因为具有栈内复用的特性;
注意点: 1)前三种启动模式,都是在同一个栈中,singleInstance 是属于自己独立的一个栈中; 2)它是单一的一个对象,独占一个栈,不会再创建;
五、singleInstancePerTask-大屏幕上构建并排功能的一种优化模式
应用场景:多窗口并排功能的时候可以使用,例如:Chrome 浏览器的多窗口
描述: 1)此模式可以用来构建并排功能,并希望在允许用户同时使用多个窗口与确保该功能仍然可用之间取得平衡。 2)使用此模式用户可以顺畅地在大屏幕设备上并排使用最多个窗口
3)和singleInstance基本一致,只是这个模式不需要再去设置不同的taskAffinity,就会有独立任务栈
六、taskAffinity属性
为实现小程序任务视图的效果需要把lauchMode声明成singleTask,且它的taskAffinity属性值也是独立的,那么这个Activity才会被放在一个单独的任务当中。
而默认情况下,每个Activity的taskAffinity属性值都是当前应用程序的包名,也就是说它们的值都是相同的,所以才不能得到我们想要的效果