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

来源:互联网 发布:牛牛抢红包软件 编辑:程序博客网 时间:2024/05/22 05:17

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@43090380MainActivity: com.example.liuwei.myapplication.MainActivity@430aac80MainActivity: com.example.liuwei.myapplication.MainActivity@430b67f0MainActivity: 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@beaa115AnotherActivity: com.example.myapp.AnotherActivity@2ceddcdMainActivity: com.example.myapp.MainActivity@19f6f985AnotherActivity: com.example.myapp.AnotherActivity@3c1fd43dMainActivity: com.example.myapp.MainActivity@12c24df5AnotherActivity: com.example.myapp.AnotherActivity@219346ad

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

三、singleTask

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

MainActivity: com.example.liuwei.myapplication.MainActivity@430902d0AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430aae90MainActivity:onNewIntent()AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430b7d30MainActivity: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@43096180AnotherActivity: com.example.liuwei.myapplication.AnotherActivity@430b0d80MainActivity: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.

1 0
原创粉丝点击