Android应用开发:Fragment与大型数据缓存
来源:互联网 发布:2017网络水军招募 编辑:程序博客网 时间:2024/04/29 17:21
引言
在Android应用开发:Fragment的非中断保存setRetaineInstance一文中已经介绍过了如何让Fragment不随着Activity销毁从而保存数据的方法。在移动应用程序的架构设计中,界面与数据即不可分割又不可混淆。在绝大部分的开发经历中,我们都是使用Fragment来进行界面编程,即使保存数据基本上也只是界面相关控件的数据,很少做其他的数据保存,毕竟这样与开发原则相背,而今天这一篇博客就要来介绍一下Fragment的另类用法,只是用来保存数据而没有任何界面元素。
实现背景
对于Fragment的数据保存方法,不难想到还是与setRetainInstance有关系的。这样一来所处的背景也是在屏幕旋转或其他配置改变时需要用到。无论在开发中我们的界面是用Activity还是Fragment生成的,在屏幕发生旋转时,都会在生命周期onSaveInstanceState中做控件状态和必要数据的缓存工作。通常情况下,会用到Bundle来存储数据。如Bundle的官方介绍所说,Bundle是一个用来存储String及其他序列化数据类型的map。同样Android中也存在着这样的一个异常:http://developer.android.com/intl/zh-cn/reference/android/os/TransactionTooLargeException.html
这个异常从字面上看不难理解,是传输数据过大异常。在描述中可知,现行Android系统中对于应用程序的传输数据大小限制在1Mb以内。所以如果在屏幕旋转过程中使用Bundle缓存大数据并不是十分安全的。这样的大数据在Android中很经典的代表之一就是Bitmap,即使Bitmap已经是序列化数据,能够方便的使用Bundle作为缓存媒介,但是笔者还是强烈不建议这样做。下边,就提供一个简单的解决途径。
实现过程
首先,创建一个用来保存数据的Fragment:
public class BitmapDataFragment extends Fragment { public static final String TAG = "bitmapsaver"; private Bitmap bitmap; private BitmapDataFragment(Bitmap bitmap) { this.bitmap = bitmap; } public static BitmapDataFragment newInstance(Bitmap bitmap) { return new BitmapDataFragment(bitmap); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } public Bitmap getData() { return bitmap; }}
这个Fragment没有任何界面,在onCreate生命周期中使用setRetainInstance(true)确保不会随载体销毁,从而确保数据的安全性。
创建完成后,实践一下使用过程,假设其使用者是Activity:
@Override protected void onSaveInstanceState(Bundle outState) { if (mBitmap != null) { getSupportFragmentManager().beginTransaction() .add(BitmapDataFragment.newInstance(mBitmap), BitmapDataFragment.TAG) .commit(); outState.putBoolean(SENSE_IMAGE_KEY, true); } else { outState.putBoolean(SENSE_IMAGE_KEY, false); } super.onSaveInstanceState(outState); }
在设备发生旋转时,检测当前界面中显示的某个Bitmap,如果确实有数据,则new出一个我们刚刚创建的Fragment,将Bitmap数据放置进去,然后将这个Fragment添加到FragmentManager中并指定tag,这样我们在恢复状态后就可以方便的找到它。
在恢复时候,Activity的生命周期走到了onCreate()中,在这里我们可以通过检测Bundle参数来确定是否有Bitmap数据待取:
if (savedInstanceState.getBoolean(SENSE_IMAGE_KEY)) { BitmapDataFragment fragment = (BitmapDataFragment) getSupportFragmentManager() .findFragmentByTag(BitmapDataFragment.TAG); bitmap = fragment.getData(); getSupportFragmentManager().beginTransaction().remove(fragment).commit();}
PS:在取出我们所需的Bitmap数据后不要忘记把作为数据容器的这个Fragment从FragmentManager中移除掉,释放其占用的系统内存。
总结
很简单的Fragment非主流用法,相比直接使用Bundle保存数据确实是复杂了些,但是能够更安全的进行数据转移对应用来说还是很好的一件事。
- Android应用开发:Fragment与大型数据缓存
- Android应用开发:Fragment与大型数据缓存
- 产品设计:Android应用-开发技术【数据缓存】
- Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- 产品设计:Android应用-开发技术【数据缓存】
- Android应用开发:Fragment
- 【Android 应用开发】 Fragment 详解
- Android Fragment与Fragment之间数据获取
- Android Fragment与Fragment之间数据获取
- Android-Fragment与Fragment之间数据获取
- 数据缓存与应用优化
- Android应用中的数据缓存
- select查询的执行顺序
- MySql通过二进制日志文件恢复数据
- APT攻击初步了解
- ubuntu-14.04-desktop-amd64 安装 Bcompare
- HTTP协议的持续连接和非持续连接
- Android应用开发:Fragment与大型数据缓存
- HDU2203 亲和串【KMP】
- 黑马程序员——Java基础---反射
- Android APK的签名与重新签名
- C/C++宏的使用总结
- HDU-1059 Dividing(DP)
- 给10^7个数据量的磁盘文件排序
- div+css之清除浮动
- 给出一个数和一个有序数组,找出该数组中之和等于该数的两个数