四种启动模式
先说显式跳转和隐式跳转
我们在开发Android应用的时候,一般MainAcitvity会设置<action android:name=“android.intent.action.MAIN” />然后我们的系统就能找到我们app的启动页面了;这就是一个隐式跳转,系统会根据action标签去在我们的清单文件manifest 中筛选出来我们设置的action.Main的activity作为第一个启动的activity;包括系统里的打开相机、打开文件等等,都是隐身跳转
//用来打开相机的Intent
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//根据intent在系统中找到合适的应用的activity,如果有多个activity可选择,
//则会弹出ResolverActivity让用户选择合适的应用。这个方法是在ActivityStack
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
profileFile, profileFd, userId);
显示 跳转就比较简单了,Intent intent = new Inent(this, LoginActivity.class);这个没什么好说的
性能方面肯定是显示跳转 要好于隐式跳转了
四个跳转模式
很简单 在同一个 Task Stack任务中
1、standard只要是startActivity,就会重新创建信的activity
2、singTask 看activity是否存在,如果存在就会把已存在的activity拿到栈顶,并且销毁在该activity之上的activity,显示出来,还会在activity中执行onNewIntent方法,表示我当前的Intent是新的,我新start了;如果不存在就正常创建,也不会执行onNewIntent方法
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
3、singTop 这个就看这个activity是否在栈顶,如果在栈顶那么跟singTask效果一样,如果 不在栈顶和standard效果一样;
4、singInstance 这个就是会开启一个独立的任务栈,只存储一个当前类型的activity
还有一个问题:singleTask和singleInstance模式下,onAcitivityResult方法执行会有影响。要用onActivityResult方法,那么这个目标activity一定不能是这种模式。
Flags
正常的启动activity还可以设置Flags,可以set设置单个Flags也可以用add组合方式
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//也可以set
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
有这样一个场景:登录Activity、注册1、注册2、注册3;四个页面
都是正常的standard 模式
当到注册3页面的时候,如果注册完成,那么直接跳到登录页面,那么就要把注册1、2、3界面都finish()掉,如果注册没完成,可以挨个返回finish()掉;典型的一个注册流程:
我们只需要这样做
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//与加载模式singleTop功能相同
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//销毁目标Activity和它之上的所有Activity,重新创建目标Activity
//这种启动模式就相当于LoginActivity是singTask了,但是实际上又不是,动态添加的Flag达到的效果
startActivity()
当然Flag还有很多很多种,列举一些常用的
FLAG_ACTIVITY_CLEAR_TOP:
例如现在的栈情况为:A B C D。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:AB。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launchmode设置成singleTask类似。
FLAG_ACTIVITY_NEW_TASK:
例如现在栈1的情况是:A BC。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Taskaffinity,并且和栈1的affinity不同,系统首先会查找有没有和D的Taskaffinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Taskaffinity默认没有设置,或者和栈1的affinity相同,则会把其压入栈1,变成:A B CD,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。
注意:如果试图从非activity的非正常途径启动一个activity,比如,从一个service中启动一个activity,则intent必须要添加FLAG_ACTIVITY_NEW_TASK标记。
FLAG_ACTIVITY_NO_HISTORY:
例如现在栈情况为:A BC。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:AB C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。
FLAG_ACTIVITY_SINGLE_TOP:和上面Activity的Launchmode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。
/Activity的主要属性:(在AndroidManifest.xml中 )
allowTaskReparenting:设置成true时,和Intent的FLAG_ACTIVITY_NEW_TASK标记类似。
alwaysRetainTaskStat: 如果用户长时间将某个task移入后台,则系统会将该task的栈内容弹出只剩下栈底的activity,此时用户再返回,则只能看到根activity了。如果栈底的activity的这个属性设置成true,则将阻止这一行为,从而保留所有的栈内容。
clearTaskOnLaunch:根activity的这个属性设置成true时,和上面的alwaysRetainTaskStat的属性为true情况搞好相反。
finishOnTaskLaunch:对于任何activity,如果它的这个属性设置成true,则当task被放置到后台,然后重新启动后,该activity将不存在了