onNewIntent()方法介绍

5,425 阅读3分钟

一、API描述如下

onNewIntent
·added in API level 1
·void onNewIntent (Intent intent)
·This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.
·An activity will always be paused before receiving a new intent, so you can count on onResume() being called after this method.
·Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.
·Parameters
intent Intent: The new intent that was started for the activity.


大概意思就是当Activity被设置为singleTop时,当需要再次响应此Activity启动需求时,会复用栈顶的已有Activity,还会调用onNewIntent()方法,并且,再接受新发送来的intent(onNewIntent()方法)之前,一定会先执行onPause()方法。


二、onNewIntent与启动模式

前提:ActivityA已经启动过,处于当前应用Activity返回栈中。

  • 当ActivityA的LaunchMode为Standard

由于每次启动ActivityA都是启动新的实例,和原来启动没有关系,因而不会调用ActivityA中的onNewIntent()方法

  • 当ActivityA的LaunchMode为SingleTop时

如果AcitivityA在栈顶,且现在要启动ActivityA,此时会调用onNewIntent()方法,生命周期顺序为:

onCreate -> onStart -> onResume ->onPause -> onNewIntent -> onResume

  • 当ActivityA的LaunchMode为SingleTask、SingleInstance

如果ActivityA已经再堆栈中,那么此时会调用onNewIntent()方法,生命周期调用顺序为

onCreate -> onStart -> onResume -> …… -> onPause -> onStop -> onNewIntent -> onRestart -> onStart -> onResume


因此,onNewIntent有可能在下列两个地方调动:(图片来源



三、注意事项

前面说到,当一个Activity已经启动时,并且存在当前应用的Activity返回栈,启动模式为singleTop、singleTask、singleInstance,那么在此启动或返回到这个Activity的时候,不会创建新的实例,也不会执行onCreate()方法,而是执行onNewIntent()方法,如下所示

protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  setIntent(intent);//must store the new intent unless getIntent() will return the old one
}

有时候,内存吃紧的情况下,系统可能会kill掉后台运行的Activity,如果不巧要启动的Activity实例被系统kill了,那么系统就会调用onCreate()方法,而不是调用onNewIntent()方法(即onCreate()onNewIntent()不会都调用只会调用其中一个方法)。这类就有个解决方法就是在onCreate()onNewIntent()方法中调用同一个处理数据的方法,如下

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  getNewIntent();
}
 
protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  setIntent(intent);//must store the new intent unless getIntent() will return the old one
  getNewIntent();
}
 
private void getNewIntent(){
  Intent intent = getIntent(); //use the data received here
}


onNewIntent()中的陷阱:

当多次启动一个栈唯一模式下的activity时,在onNewIntent()里面的getIntent()得到的intent感觉都是第一次的那个数据。

这儿会有个陷阱,因为它就是会返回第一个intent的数据,就是这个坑。

原因是因为没有onNewIntent()里面设置setIntent(),即将最新intent设置在这个activity实例中。

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);//设置新的intent
    int data = getIntent().getIntExtra("tanksu", 0);//此时的到的数据就是正确的了
}