一次搞懂Activity的启动方式和启动模式

一、Activity的启动方式

1.显式

方法一 构造方法传入Component,最常用的方式

Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

方法二 setComponent方法

ComponentName componentName = new ComponentName(this, SecondActivity.class);

Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);

方法三 setClass/setClassName方法

Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);
startActivity(intent);

2.隐式

首先AndroidManifest.xml文件中配置


        
            
            
        

方法一 setAction方法

Intent intent = new Intent();
intent.setAction("second");
startActivity(intent);

方法二 构造方法直接设置Action,通过设置Action字符串,表明自己的意图,即我想干嘛,需要由系统解析,找到能够处理这个Intent的Activity并启动。比如我想打电话,则可以设置Action为"android.intent.action.DIAL"字符串,表示打电话的意图,系统会找到能处理这个意图的Activity,例如调出拨号面板。

Intent intent = new Intent("second");
startActivity(intent);

二、Activity的启动模式

任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名.

standard : 标准模式
每次启动Activity都会创建一个新的Activity实例,并且将其压入任务栈栈顶,而不管这个Activity是否已经存在。Activity的启动三回调(onCreate()->onStart()->onResume())都会执行

使用场景:

所有的Activity遵循元素进栈出栈的特性,例如进栈序列为A->B->C->D,D呈现在页面上,按返回键出栈顺序久违D->C->B->A。如果不指定开启模式一般都是默认的
singleTop : 栈顶复用模式
这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,所以它的启动三回调就不会执行,同时Activity的onNewIntent()方法会被回调.如果Activity已经存在但是不在栈顶,那么作用与standard模式一样

使用场景:

1.消息推送,通知栏弹出Notification,点击Notification跳转到指定Activity,但是如果我现在页面就停留在那个指定的Activity,会再次打开我当前的Activity,这样返回的时候回退的页面和当前页面一样,感官上就会很奇怪。
2.登录的时候,登录成功跳转到主页,按下两次登录按钮,生成了两个主页。一些有启动延迟的页面(往往是动画,网络造成)也会有这样的情况。(多次连续点击按钮跳转问题)
singleTask: 栈内复用模式
创建这样的Activity的时候,系统会先确认它所需任务栈已经创建,否则先创建任务栈.然后放入Activity,如果栈中已经有一个Activity实例,那么这个Activity就会被调到栈顶,onNewIntent(),并且singleTask会清理在当前Activity上面的所有Activity.(clear top)

使用场景:

问题:
做浏览器、微博之类的应用,比如其他App需要打开我们的浏览器页面,就可以配置他为singleTask模式,保证他只有一个唯一实例,节约内存同时按下返回键后的感官也更顺畅。但是需要注意,提供给人调用的页面最好是栈底元素。因为,如果自己的客户端处于运行状态,按下Home键后台挂起。此时如果使用如果其他应用(比如说QQ)调起自己的客户端某个页面,不做任何处理的情况下,按下回退或者当前 Activity.finish(),页面都会停留在自己的客户端(因为自己的Application回 退栈不为空),这明显不符合逻辑的。 
解决方案:
1.利用singleTask清除这个activity任务栈上面所有的activity特性。我们提供的分享页面始终是我们栈底的元素,只要他一启动就会清空任务栈内其他Activity,保证只有他一个实例。
2.android:taskAffinity=”要打开本应用的其他应用包名”
  
        
            

            
        
    
如果com.test.newlaunch没启动就新建一个任务栈,如果com.test.newlaunch启动了就直接加入它的任务栈。
singleInstance : 加强版的singleTask模式
这种模式的Activity只能单独位于一个任务栈内,由于栈内复用的特性,后续请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了

使用场景:

单一实例模式,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。 

终结:Android使用android:launchMode="standard|singleInstance|singleTask|singleTop"来控制Acivity任务栈,Activity的堆栈管理以ActivityRecord为单位,所有的ActivityRecord都放在一个List里面.可以认为一个ActivityRecord就是一个Activity栈

你可能感兴趣的:(一次搞懂Activity的启动方式和启动模式)