Android中FragmentPagerAdapter对Fragment的缓存(一)
2016-05-24 17:24
701 查看
ViewPager + FragmentPagerAdapter,时我们经常使用的一对搭档,其实际应用的代码也非常简单,但是也有一些容易被忽略的地方,这次我们就来讨论下FragmentPagerAdapter对Fragment的缓存应用。
我们可以先看看最简单的实现,自定义Adapter如下:
[代码]java代码:
?[代码]java代码:
?接下来,我们来模拟一下程序运行在后台时,Android系统由于内存紧张,杀掉我们程序进程的情况:
首先运行程序至前台
接下来,点击Home键,返回桌面,同时我们的程序退回至后台运行。
进入Android Studio中,点击Android Monitor这个tab,并选择当前Device,并选择我们程序的进程名。
点击Terminal Application这个小红叉按钮,如下图:
这个时候后台进程已经被杀掉了,但是应用程序历史里我们的应用还在,所以长按Home键,并选择我们的程序,让其恢复到前台。
这时会看到,程序的确恢复到之前的页面。但奇怪的是,页面上却只有Hello,我们之前传入的Two到哪里去了?
Fragment代码也比较简单,通过日志,我们发现恢复时,mText字段为空。所以页面上对应的TextView无法显示。
[代码]java代码:
?那么当上面的流程发生时,Activity的onSaveInstanceState会被调用,以便我们可以保存当前的用户数据/页面状态等。当恢复时,在onCreate时,我们通过savedInstanceState参数,可以取到之前存储的数据,然后重新绑定到View上。
这个过程都可以理解,可是回到我们的Activity代码当中:
[代码]java代码:
?难道说,呈现在屏幕上的Fragment,和我们在onCreate中实例化的Fragment,已然不是同一个实例?
为了验证这个想法,在OnCreate中加入下面的日志:
[代码]java代码:
?[代码]java代码:
?[代码]java代码:
?[代码]java代码:
?看来,还是要从源码中寻求真相,打开FragmentPagerAdapter的源码,在instantiateItem方法中发现了下面这一段:
[代码]java代码:
?[代码]java代码:
?而makeFragmentName产生的tag,只受我们重写的getItemId()方法返回值,和当前容器View的Id,container.getId()的影响。
到这里,问题就清楚了,由于FragmentPagerAdapter会主动的去取缓存当中的Fragment,所以导致恢复回来之后,Fragment的实例不一样的问题。
至于为什么mText字段为空,以及怎样解决这个情况,我们下一篇再来讨论^_^。
相关文章推荐
- Xposed插件Android.EagleEye
- android 分割线渐变色和几种颜色值定义
- Android开发中View的事件分发探秘
- Android 平滑图片加载和缓存库 Glide 使用详解
- Android使用注解避免大量的findViewById()
- Android N的介绍
- Android平台手机 5大优势和劣势
- android socket 客户端 服务器端
- 图片下载之缓存
- Android KITKAT 以上实现沉浸式状态栏
- Android 缓存框架——ASimpleCache
- Android中ListView的滚动条隐藏
- 反射、注解与依赖注入总结
- android handler机制学习
- android实现聊天页面的气泡
- Android输入法隐藏
- Android内存优化之取代HashMap(SparseArray和ArrayMap解析)
- ListView学习
- Android屏幕适配全攻略(最权威的官方适配指导)
- android之自定义View和ViewGroup(四)(代码篇,实现圆形进度条)