Android onNewIntent()需要注意的一些问题
来源:互联网 发布:交易宝行情软件 编辑:程序博客网 时间:2024/05/29 13:36
一、场景
最近遇到一个需求:有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: - onCreate06-16 13:58:58.889 15959-15959/zz.mk.zgarden E/TAG: - onStart06-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: - onPause06-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: - onNewIntent06-16 13:59:31.181 15959-15959/zz.mk.zgarden E/TAG: - onRestart06-16 13:59:31.181 15959-15959/zz.mk.zgarden E/TAG: - onStart06-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游戏开发中需要注意的一些问题
- Android替换字体时需要注意的一些问题
- XHTML MP 需要注意的一些问题
- 使用IOCP需要注意的一些问题
- SQL需要注意的一些问题
- Css中需要注意的一些问题
- W3C需要注意的一些问题
- C语言需要注意的一些问题
- C++程序员需要注意的一些问题
- 编程需要注意的一些问题
- 上线app需要注意的一些问题
- 使用ViewStub需要注意的一些问题
- VC.NET 需要注意的一些问题
- vector使用需要注意的一些问题
- C语言一些需要注意的问题
- Linux系统安全需要注意的一些问题
- fork()需要注意的一些问题
- day09 ARM汇编指令
- Struts2 重定向 乱码解决方案
- java实现单向链表的常用操作
- Java线上应用故障排查之二:高内存占用
- rsync+inotify-tools实时同步真正可用版
- Android onNewIntent()需要注意的一些问题
- day10 ARM伪指令、ARM混合调用
- day11 ARM混合调用案例、ARM核 异常处理流程、软件处理异常
- Android安装APK详解
- 利用serializable将对象保存到本地
- 数据结构与算法汇总
- unity c#调用c++ dll相关技术细节整理
- jquery与JavaScript部分使用区别
- WMI技术介绍和应用——WMI概述