Activity onNewIntent方法浅析

我们知道,我们可以通过startActivity(Intent intent)方法来启动一个新的activity,其中intent负责交互数据的传递。当新启动的activity已经存在并且可复用的时候,情况就会发生一些微妙变化。原来启动传入的intent数据会不会消失?新传入的intent会不会立即生效?在Activity中有个onNewIntent()方法,通过分析它,可以理解在复用activity的数据传递问题。

onNewIntent方法一般用于lanchmode为singleTop,singleTask,singleInstance等可复用的activity中,当这些已实例化的activity重新被复用时,就会调用onNewIntent方法。正如字面上的意思,onNewIntent负责处理activity收到的新intent。

Activity中onNewIntent源码如下:

/**
     * This is called for activities that set launchMode to "singleTop" in
     * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
     * flag when calling {@link #startActivity}.  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.
     *
     * <p>An activity will always be paused before receiving a new intent, so
     * you can count on {@link #onResume} being called after this method.
     *
     * <p>Note that {@link #getIntent} still returns the original Intent.  You
     * can use {@link #setIntent} to update it to this new Intent.
     *
     * @param intent The new intent that was started for the activity.
     *
     * @see #getIntent
     * @see #setIntent
     * @see #onResume
     */
    protected void onNewIntent(Intent intent) {
    }

首先我们来看这句话:

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(Intent intent) will be called on the existing instance with the Intent that was used to re-launch it.

意思是当activity没有建立新实例,而是被重新复用并且处于任务栈的栈顶时,该activity的onNewIntent(Intent intent)方法会执行,其中的intent参数为复用activity的intent。

An activity will always be paused before receiving a new intent, so you can count on being called after this method.

onNewIntent()方法会在onResume()方法之前执行,这样我们可以在onNewIntent方法对新传来的intent进行一些处理。

Note that {@link #getIntent} still returns the original Intent. You can use {@link #setIntent} to update it to this new Intent.

值得注意的是,当我们复用activity时,getIntent()方法依旧返回的是原来的intent。可以看到,传入的新intent并没有立即生效,只是放在onNewIntent方法的参数中,原来的intent数据也没有消失,我们可以根据需求随意调用旧intent的或新intent,如果需要在复用activity过程中获取新intent中的数据,需要采用如下方式:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent != null)
            setIntent(intent);
    }

再在onResume()方法里调用getIntent(),即可得到新的数据。

另外,onNewIntent()代码说明里提到:

 /**
     * This is called for activities that set launchMode to "singleTop" in
     * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
     * flag when calling {@link #startActivity}. 
 * /

这句话的意思是,onNewIntent()这个方法能被launchmode为singleTop 或 Intent Flag为FLAG_ACTIVITY_SINGLE_TOP的activity复用时调用。但是,launchmode 为singleTask,singleIntance 的activity也可以被复用,也会调用onNewIntent()方法,说明里为什么没有提及呢?个人觉得是singleTask,singleIntance 内部实现中也设置了FLAG_ACTIVITY_SINGLE_TOP flag ,有兴趣的朋友可以帮我解答~另外,让很多人困惑的是,当我们使用FLAG_ACTIVITY_SINGLE_TASK 时,为避免出现activity多实例,必须加上FLAG_ACTIVITY_SINGLE_TOP 标签,有的人说这是一个BUG,不知道它们看了onNewIntent()的说明后,还会这么认为吗?我把它理解成FLAG_ACTIVITY_SINGLE_TOP flag就是为了调用onNewIntent()存在的。不过可以肯定的是,google的android doc还有待完善平衡……

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值