Activity的四种启动模式和应用场景

简介
通过设置ActivityManifestActivity_launchMode可以设置Activity的启动模式。

默认情况下,使用启动模式:standard。

同时,launchMode可以通过Intent flags的改变在运行时被复写,比
如 Intent flags FLAG_ACTIVITY_SINGLE_TOP, FLAG_ACTIVITY_NEW_TASK,
FLAG_ACTIVITY_MULTIPLE_TASK.

四种模式
Constant      Value    Description

standard        0    默认模式,会在启动时创建一个新实例,创建的模式也可以随Intent.FLAG_ACTIVITY_NEW_TASK而改变

singleTop      1    当启动activity时,有相同的activity在前台与用户交互,那就复用这个activity,这个实例会被调用Activity.onNewIntent()。

singleTask     2    在启动activity时,若有一个运行着这个activity的task,那这个activity实例会被调到前台,并调用Activity.onNewIntent() ,启动实例的Intent的flag会被设置Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT . singleTask是singleTop的一个扩展集。This is a superset of the singleTop mode, where if there is already an instance of the activity being started at the top of the stack, it will receive the Intent as described there (without the FLAG_ACTIVITY_BROUGHT_TO_FRONT flag set). See the Tasks and Back Stack document for more details about tasks.

singleInstance 3   开辟一个只允许一个activity实例在里头运行的task. 如果用同样的intent再次启动这个activity,task会被调到前台,其Activity.onNewIntent() 会被调用. 如果这个activity实例要启动一个新activity,那么这个新activity会在一个新task中运行.

Demo范例调试
目录结构:MainActivity、Activity1\Activity2、Activity3

唯一的一个layout



    

    

几个除了红色字体外,其余全部一模一样的Activity

public class Activity2 extends ActionBarActivity {

Button mBtnAct1, mBtnAct2, mBtnAct3;

TextView mTxtThis;

    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTxtThis = (TextView) findViewById(R.id.txt_this);
        mTxtThis.setText(Activity2.this.toString());
        Log.e("TestLauncherMode", Activity2.this + " onCreate");
        mBtnAct1 = (Button) findViewById(R.id.btn_activity_1);
        mBtnAct1.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                        Log.e("TestLauncherMode", Activity2.this + " navigate to Activity1");
                        startActivity(new Intent(getBaseContext(), Activity1.class));
                }
        });

        mBtnAct2 = (Button) findViewById(R.id.btn_activity_2);
        mBtnAct2.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                        Log.e("TestLauncherMode", Activity2.this + " navigate to Activity2");
                        startActivity(new Intent(getBaseContext(), Activity2.class));
                }
        });

        mBtnAct3 = (Button) findViewById(R.id.btn_activity_3);
        mBtnAct3.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                        Log.e("TestLauncherMode", Activity2.this + " navigate to Activity3");
                        startActivity(new Intent(getBaseContext(), Activity3.class));
                }
        });
    }

    public void onStop(){
     super.onStop();
     android.util.Log.e("TestLauncherMode", Activity2.this + " onStop");
    }

}

红色字体,相应替换就OK了。

AndroidManifest.xml

  ......
        
            
                
                
            
        

        

        

        

  ......

前提注释:从Launcher启动的Activity,肯定是NEW_TASK。这点可以查看Launcher的源码。

模式1:standard。默认模式。
操作如下:MainActivity->Activity1->Activity1->Activity1->Back->Back->Back->Back

仔细看一下這个log转换成图形

这是默认的启动模式,每次启动,都启动一个new Instance。

模式2:singleTop
这个范例把Activity1的launchMode=”singleTop”

操作如下:
MainActivity->Activity1->Activity1->Activity1->Activity1->Activity1->Activity2->Activity3->Activity1->Activity1->Back->Back->Back->Back

仔细看navigate的字段,这些是点击跳转时打印的动作信息。

转换成图形

可以看出,当task顶部有singleTop的Activity时,就复用;若没有就重新创建。

singleTop:就是栈顶只有一个instance。

适合  接受推送消息的展示页

某些本应只展示一个的场景,比如一下子收到一堆推送消息,不能每个都弹出来吧。但凡是这样的都行。优酷的推荐视频,电商app推送一个活动。

模式3:singleTask---Activity2设置成singleTask

转换成图形

为什么会这样呢。因为Activity2是singleTask,如果task里没有就new,若有,就把Activity2之上的全部移除掉。这样,自己就变成了顶。所以说,singleTask是singleTop的扩展。

singleTop:顶上不是target Activity,new一个

singleTask:顶上不是target Activity,移除target之上的,把自己变成top。

singleTask的特性是头上不允许有任何task。也不会有重复的instance。在target Activity之后的任何activity都会被干掉。等于重生啊。

适合程序入口,不需要启动后activity的

是的,只能用在启动页了吧,首页,这种只允许有一个instance,如果有其他就移除掉它顶上的。从这个Activity进入的其他activity都抛弃掉了。用户要再操作一次。

官网的文档说----make sure to test the usability of the activity during launch

确实,得好好考虑下,不是所有activity都可以用的

模式4:singleInstance-activity2设置成singleInstance


转换成图形

这图有点复杂。两个框代表两个task,这应没什么问题。下框没连接部分,都跑到Activity2去了。

可以看到一启动到Activity2就会重新开辟一个task。而这里头的task只有一个activity2.

在返回的时候,是一个task,一个task的返回的。

要从当前的task开始,上图task2结束后就跳转到task1了。

singleInstance的特性是  完全同程序分离。完全独立运行的。

同样的也要想清楚再用。

适合需要与程序分离开的页面。

这种页面包括,闹钟的提示框。有兴趣的朋友可以看下package/app下的源码,grep一把,就会发现是这样的

框内是内部apk的独特应用。也用的singleInstance。就不混淆视听了。

 

小结
使用方式:

standard:怎么样都要创建

singleTop:顶上不是target Activity,new一个

singleTask:顶上不是target Activity,移除target之上的,把自己变成top。

singleInstance:开辟私有的task,完全独立于程序的其他activity的task。

使用场景:

standard:普通activity

singleTop:要展示推送过来的消息

singleTask:程序入口等启动页面

singleInstance:完全独立的,类似闹钟的提示

你可能感兴趣的:(四大组件和Fragment)