Activity的四种launchMode以及onNewIntent()的调用时机

Android的Activity一共有四种launchMode:standard、singleTop、singleTask、singleInstance,在AndroidManifest.xml中用来指定Activity的启动方式。

一、standard

activity的默认启动方式,未指定android:launchMode的属性时默认为standard。

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("", "MainActivity: " + this.toString());
        findViewById(R.id.start_new_activity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, MainActivity.class));
            }
        });
    }
}

三次点击start_new_activity,结果如下:

MainActivity: com.example.liuwei.myapplication.MainActivity@43090380
MainActivity: com.example.liuwei.myapplication.MainActivity@430aac80
MainActivity: com.example.liuwei.myapplication.MainActivity@430b67f0
MainActivity: com.example.liuwei.myapplication.MainActivity@430c1ab8

可以发现,同样的MainActivity创建了四个不同的实例,点击四次返回键,才可以退出整个APP。
standard启动模式中,不管有没有已经存在的实例,都会创建一个新的实例。

二、singleTop

指定launchMode为singleTop,重复执行上述操作,结果如下:

MainActivity: com.example.myapp.MainActivity@3c8362e9

同时APP并没有出现activity之间跳转的现象,点击返回键直接退出当前APP,说明当指定为singleTop时,栈中只有一个MainActivity的实例。在MainActivity中重写onNewIntent()方法,发现点击按钮时都会调用一次onNewIntent()方法。

创建一个新的Activity,执行其launchMode为singleTop。让MainActivity和AnotherActivity互相跳转。
代码如下:

public class AnotherActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("111111111111111", "AnotherActivity: " + this.toString());
        findViewById(R.id.start_new_activity).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        startActivity(new Intent(AnotherActivity.this,
                                MainActivity.class));
                    }
                });
    }

    @Override
    protected void onNewIntent(Intent intent) {
        // TODO Auto-generated method stub
        super.onNewIntent(intent);
        Log.e("111111111111", "onNewIntent()");
    }
}

执行APP,点击跳转按钮,结果如下:

MainActivity: com.example.myapp.MainActivity@beaa115
AnotherActivity: com.example.myapp.AnotherActivity@2ceddcd
MainActivity: com.example.myapp.MainActivity@19f6f985
AnotherActivity: com.example.myapp.AnotherActivity@3c1fd43d
MainActivity: com.example.myapp.MainActivity@12c24df5
AnotherActivity: com.example.myapp.AnotherActivity@219346ad

在互相跳转的过程中,MainActivity和AnotherActivity每次都会创建一个新的实例,而没有使用原有的实例。
当launchMode指定为singleTop时,如果要启动的Activity正处于栈的顶端,则重复利用原有的Activity,不再创建新的实例。

三、singleTask

指定MainActivity和AnotherActivity的launchMode均为singleTask。
重复之前的操作,结果如下:

MainActivity: com.example.liuwei.myapplication.MainActivity@430902d0
AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430aae90
MainActivity:onNewIntent()
AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430b7d30
MainActivity:onNewIntent()
AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430c3bc0

MainActivity的实例只会创建一次,之后都是重用之前的实例,而AnotherActivity每次都会创建新的实例。

过程如下:

  • 第一次创建一个MainActivity的实例;
  • 然后创建一个AnotherActivity的实例;
  • 再次进入MainActivity时,已经存在实例,直接使用,但是这时候会将栈顶MainActivity实例之后的所有activity出栈;
  • 再次进入AnotherActivity时,已经找不到AnotherActivity的实例,无法复用,只能创建一个新的AnotherActivity的实例了。

    在singleTask模式中,如果发现已经有activity的实例,则复用该实例,但此实例之上的其他实例都会出栈。

四、singleInstance

指定MainActivity和AnotherActivity的launchMode为singleInstance。重复之前的操作,结果如下:

MainActivity: com.example.liuwei.myapplication.MainActivity@43096180
AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430b0d80
MainActivity:onNewIntent()
AnotherActivity:onNewIntent()
MainActivity:onNewIntent()
AnotherActivity:onNewIntent()

MainActivity和AnotherActivity分别创建了一个实例,之后都是在复用之前创建的实例。点击返回键,两次就退出整个APP。

查阅资料发现,MainActivity和AnotherActivity的实例分别位于两个不同的栈中,栈中有实例的时候,直接复用实例。

指定为singleInstance的activity,创建时会进入一个新的栈并独占该栈,之后不会再创建实例,而是直接使用之前栈中的实例,除非该实例已经被销毁(比如执行了返回)。而新创建的其他activity的实例会进入到其他栈中,不会进入指定为singleInstance的activity创建的栈中。

五、onNewIntent(Intent intent)的调用时机

在上述代码中,可以看到,每次重用activity实例的时候,都会调用onNewIntent()。

重用实例的生命周期如下:
onNewIntent() –> onRestar() –> onStart() –> onResume()

注意:重用实例时如果涉及到通过Intent传递参数,那么在onNewIntent中一定执行一次setIntent(intent),否则会导致通过getInent()拿到的intent是旧数据,而不是最新的参数。

Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值