Android onNewIntent()需要注意的一些问题
2017-06-16 17:20
337 查看
一、场景
最近遇到一个需求:有A、B、C三个页面,A能跳到B,然后B会跳到C,C还能跳到B,反正B和C两个页面能互相跳,但是C页面点击返回的时候要回到A。(ps:页面之间有数据的传递)
拿到需求我一下就想到的方案就是 把 B、C两个页面的启动模式设置成SignleTask:
二、遇到问题
然而事实总是残酷的,测试总是牛批的。当测试拿着数据来找我的时候我也懵了。经过调试我发现数据有点不对劲,因为B跳转C的时候会传递一个值(这里记为第一次给C传值),C里面会做一些操作然后更新数据传给B,B接收到数据然后更新第一次传递的值再传给C(这里记为第二次传值)。但是通过log发现第一次和第二次传递的值根本没有变化!
经过查找我发现了onNewIntent()的问题,这里看看文档怎么解释的:
通过文档我们需要了解到的信息是:onNewIntent() 这个方法只有当进入一个已经打开过的Activity时才会调用,也就是第一次进入这个Activity时不会调用。而且如果两个acticity之间使用intent传值的话,第二次通过getIntent()获取的值将还是上一次的值!!!
终于在这里发现了我所遇到的问题所在,开篇我说过我的C使用的SingleTask,而B在跳转前都会finish() 掉自己,所以C一直处于栈顶,所以当第二次跳转C时我的getIntent获取的还是旧的值,所以导致数据没变。
三、实验
下面通过实验来测试下,因为代码简单这里只提供主要的实验思路:
思路:定义两个Activity:A和B。启动模式都设置成SingleTask,A点击跳转B并传一个参数,然后finish A;B在点击跳转A也传递一个参数,用于判断修改第一次A传递给B的值。然后在B里面打印两次获取参数的值。
1、重写的几个主要的生命周期:
这里第一次我传递的是“1”,第二次传递的是“2”。
结果:(这里打印的只有TestActivity 的生命周期)
根据结果我们能够看到第二次进入的时候onCreate方法压根都没走,onNewIntent正如文档所说第一次也没走。而我们一般获取参数都在onCreate里面获取,所以这样会导致参数不会变化。
既然知道了问题出在哪了,我们就知道怎么解决了。
这里我们只要在onCreate和onNewIntent里面都调用同一个获取参数的方法就好了:
上面注意在onNewIntent方法里面要调用下
今天的分享就到这里了,有问题欢迎指出~~
最近遇到一个需求:有A、B、C三个页面,A能跳到B,然后B会跳到C,C还能跳到B,反正B和C两个页面能互相跳,但是C页面点击返回的时候要回到A。(ps:页面之间有数据的传递)
拿到需求我一下就想到的方案就是 把 B、C两个页面的启动模式设置成SignleTask:
android:launchMode="singleTask", 在B Intent跳转C时将B finish()掉,因为C在Activity栈里面永远也只有一个实例,这样当C点击返回时就会返回A了。~~细细一想没发现什么问题,很完美。
二、遇到问题
然而事实总是残酷的,测试总是牛批的。当测试拿着数据来找我的时候我也懵了。经过调试我发现数据有点不对劲,因为B跳转C的时候会传递一个值(这里记为第一次给C传值),C里面会做一些操作然后更新数据传给B,B接收到数据然后更新第一次传递的值再传给C(这里记为第二次传值)。但是通过log发现第一次和第二次传递的值根本没有变化!
经过查找我发现了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) { }
翻译: 当Activity启动方式设置成 singleTop,或者程序里面调用startActivity时使用FLAG_ACTIVITY_SINGLE_TOP标签时这个方法会被调用。无论哪种情况 只要当Activity在Activity栈的栈顶被重新启动而不是重新生成一个新的Activity实例时,onNewIntent()就会在之前那个已经启动过的Activity里面被调用。 在接收到新意图之前,Activity将始终处于暂停状态,因此您可以依赖此方法后调用onResume。 注意:getIntent() 始终返回的是之前的intent所传的数据,你可以使用setIntent(intent)去更新数据
通过文档我们需要了解到的信息是:onNewIntent() 这个方法只有当进入一个已经打开过的Activity时才会调用,也就是第一次进入这个Activity时不会调用。而且如果两个acticity之间使用intent传值的话,第二次通过getIntent()获取的值将还是上一次的值!!!
终于在这里发现了我所遇到的问题所在,开篇我说过我的C使用的SingleTask,而B在跳转前都会finish() 掉自己,所以C一直处于栈顶,所以当第二次跳转C时我的getIntent获取的还是旧的值,所以导致数据没变。
三、实验
下面通过实验来测试下,因为代码简单这里只提供主要的实验思路:
思路:定义两个Activity:A和B。启动模式都设置成SingleTask,A点击跳转B并传一个参数,然后finish A;B在点击跳转A也传递一个参数,用于判断修改第一次A传递给B的值。然后在B里面打印两次获取参数的值。
1、重写的几个主要的生命周期:
public class TestActivity extends BaseActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); LogUtil.zLog().e("onCreate"); } @Override protected void onStart() { super.onStart(); LogUtil.zLog().e("onStart"); } @Override protected void onRestart() { super.onRestart(); LogUtil.zLog().e("onRestart"); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); LogUtil.zLog().e("onNewIntent"); } @Override protected void onResume() { super.onResume(); LogUtil.zLog().e("onResume"); } @Override protected void onPause() { super.onPause(); LogUtil.zLog().e("onPause"); } @Override protected void onStop() { super.onStop(); LogUtil.zLog().e("onStop"); } }
这里第一次我传递的是“1”,第二次传递的是“2”。
结果:(这里打印的只有TestActivity 的生命周期)
第一次进入 TestActivity 06-16 13:58:58.889 15959-15959/zz.mk.zgarden E/TAG: - onCreate 06-16 13:58:58.889 15959-15959/zz.mk.zgarden E/TAG: - onStart 06-16 13:58:58.909 15959-15959/zz.mk.zgarden E/TAG: - onResume //点击离开页面后 06-16 13:59:19.239 15959-15959/zz.mk.zgarden E/TAG: - onPause 06-16 13:59:20.060 15959-15959/zz.mk.zgarden E/TAG: - onStop 第二次进入TestActivity 06-16 13:59:31.171 15959-15959/zz.mk.zgarden E/TAG: - onNewIntent 06-16 13:59:31.181 15959-15959/zz.mk.zgarden E/TAG: - onRestart 06-16 13:59:31.181 15959-15959/zz.mk.zgarden E/TAG: - onStart 06-16 13:59:31.191 15959-15959/zz.mk.zgarden E/TAG: - onResume
根据结果我们能够看到第二次进入的时候onCreate方法压根都没走,onNewIntent正如文档所说第一次也没走。而我们一般获取参数都在onCreate里面获取,所以这样会导致参数不会变化。
既然知道了问题出在哪了,我们就知道怎么解决了。
这里我们只要在onCreate和onNewIntent里面都调用同一个获取参数的方法就好了:
@Override protected void onCreate(@Nullable Bundle savedInstanceState){ super.onCreate(savedInstanceState); getExtraData(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); // intent.getStringExtra("TEST"); getExtraData(); } private void getExtraData(){ test = getIntent().getStringExtra("TEST"); TextView.setText(test); }
上面注意在onNewIntent方法里面要调用下
setIntent(intent);不然数据还是不会变化,当然也可以直接使用
intent.getStringExtra("TEST");获取的数据也是新的。不过充代码复用角度来看的话还是setIntent比较好点。
今天的分享就到这里了,有问题欢迎指出~~
相关文章推荐
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- android onNewIntent和使用通知时问题
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Android替换字体时需要注意的一些问题
- Android:onNewIntent()触发机制及注意事项
- Android:onNewIntent()触发机制及注意事项
- Cocos2d-x 3.0 Android修改APK名、更改图标、修改屏幕方向、修改版本号,一些需要注意的问题
- android onNewIntent 问题
- Android:onNewIntent()触发机制及注意事项
- Android初学习 - onNewIntent()触发机制及注意事项