Android基础篇 Android 数据存储与性能
创始人
2024-02-16 15:58:44

文章目录

  • 前言
      • 有关Android存储
      • SharedPreferences 共享首选项
      • 静态变量存储方式
      • 到底使用哪一种存储方式?
      • 文件存储方式(实战工具类)
      • 数据库存储方式(实战工具类)

前言

最近到了一家公司,跟一个同事做项目,比如常规的一些操作用SharedPreferences就很好搞定,他跟我说SharedPreferences 会影响性能说了一堆… 难道别的存储方式就不耗费性能吗?不消耗内存吗?

有关Android存储

Android中的数据存储方案主要有:共享首选项(SharedPreferences)、内部存储(Internal Storage)、外部存储(External Storage)、SQLite数据库、 网络存储 静态变量等

SharedPreferences 共享首选项

先说一下SharedPreferences 简称SP , SharedPreferences类提供了一个通用框架,使开发者能够以键值对的方式,永久性的保存一些原始数据类型的数据,包括:布尔值,浮点值,整型值,长整型和字符串,被保存的数据可以跨多个用户会话永久保留(即使应用已经终止)。

为什么使用 SP 它的优点是什么? 使用SP 为Android开发者提供了更为便利的存储方式,但是相对的他也是有一些缺点的。

当我们首次创建 SharedPreferences 对象时,会根据文件名将文件下内容一次性加载到 mMap(SharedPreferencesImpl 成员) 容器中,每当我们 edit 都会创建一个新的 EditorImpl 对象,当修改或者添加数据时会将数据添加到 mModifiled (EditorImpl 成员)容器中,然后 commit 或 apply 操作比较 mMap 与 mModifiled 数据修正 mMap 中最后一次提交数据,然后写入到文件中。而 get 直接从 mMap 中读取。试想如果此时你存储了一些大型 key 或 value 它们会一直存储在内存中得不到释放。

(1) 不要存放大的 key 和 value 在 SharedPreferences 中,否则会一直存储在内存中得不到释放,内存使用过高会频发引发GC,导致界面丢帧甚至ANR (2) 不相关的配置选项最好不要放在一起,单个文件越大读取速度则越慢。 (3) 读取频繁的 key 和不频繁的 key 尽量不要放在一起(如果整个文件本身就较小则忽略,为了这点性能添加维护得不偿失)。 (4) 尽量不要存放 JSON 和 HTML,这种可以直接文件缓存。Json/HTML 文件较小忽略不计! (5) 不要指望这货能够跨进程通信 Context.PROCESS

静态变量存储方式

因为这种方式我与我一个同事有了一些意见不一的地方,他喜欢使用静态变量。现在的开发是针对于设备开发,而并非手机app的开发,如果app开发他的那种搞法非得出现问题不可。 因为Activity初始化的静态变量也会被置空,因此它的生命周期是不稳定的。也就是说,在Android中静态变量可能随时被系统置空,变为null,其它地方在使用的时候就会产生空指针现象

在Android开发中不提倡过多使用static类型的变量(除了 static final)因为静态变量生命周期较长,而且不易被系统回收,因此如果不能合理地使用静态变量,就会适得其反,造成大量的内存浪费,所谓过犹不及。 经过我的多方查证 建议在具备下列全部条件的情况下,尽量使用静态变量: (1) 变量所包含的对象体积较大,占用内存较多。 (2) 变量所包含的对象生命周期较长。 (3) 变量所包含的对象数据稳定。 (4) 该类的对象实例有对该变量所包含的对象的共享需求。 如果变量不具备上述特点建议你不要轻易地使用静态变量,以免弄巧成拙。 对于全局变量使用Android提供了 Application 其生命周期与应用程序共存亡。所以对于全局变量可以写在 Application。

到底使用哪一种存储方式?

(1) 如果是简单的数据结构,首选 SharedPreferences (2) 如果是数据量大处理复杂的话,首选是sql数据库 对于结构化的数据,一定要使用数据库,虽然会显得比较麻烦,但是后续的使用中会获益无穷 (3) 普通文件就是指文本文件,二进制文件,多媒体文件,还有频繁的读取要是用二进制文件。 (4) 使用网络存储时要避免传输大数据量数据,应注意对网络传输方式的优化(减少请求次数等)。

文件存储方式(实战工具类)

文件存储方式工具类

数据库存储方式(实战工具类)

数据库最近学会的是一个DAO 简直爱死这个了,处理数据库数据是真的轻松。

示例:

  public class DbController {/*** Helper*/private DaoMaster.DevOpenHelper mHelper;/*** 数据库*/private SQLiteDatabase db;/*** DaoMaster*/private DaoMaster mDaoMaster;/*** DaoSession*/private DaoSession mDaoSession;/*** 上下文*/private Context context;private static DbController mDbController;/*** dao*/private StudentsDao studentsDao;/*** 获取单例*/public static DbController getInstance(Context context) {if (mDbController == null) {synchronized (DbController.class) {if (mDbController == null) {mDbController = new DbController(context);}}}return mDbController;}/*** 初始化** @param context*/public DbController(Context context) {this.context = context;mHelper = new DaoMaster.DevOpenHelper(context, "person.db", null);mDaoMaster = new DaoMaster(getWritableDatabase());mDaoSession = mDaoMaster.newSession();studentsDao = mDaoSession.getStudentsDao();//  diningRoomDao = mDaoSession.getDiningRoomDao();}/*** 获取可写数据库** @return*/private SQLiteDatabase getWritableDatabase() {if (mHelper == null) {mHelper = new DaoMaster.DevOpenHelper(context, "person.db", null);}SQLiteDatabase db = mHelper.getWritableDatabase();return db;}public boolean execSQL(String sql) {if (db == null) {db = getWritableDatabase();}try {db.execSQL(sql);return true;} catch (SQLException s) {Log.e("SQLException", s.getMessage());return false;}}/*** 插入学生数据** @param*/public void insertStudents(Students studentsData) {studentsDao.insertOrReplace(studentsData);}/*** 批量插入学生数据*/public void saveStudentLists(final List list) {if (list == null || list.isEmpty()) {return;}studentsDao.getSession().runInTx(new Runnable() {@Overridepublic void run() {for (int i = 0; i < list.size(); i++) {Students studentsData = new Students();studentsData.setLast_change_id(list.get(i).getLast_change_id());studentsData.setClass_name(list.get(i).getClass_name());studentsDao.insertOrReplace(studentsData);}}});}/*** 修改学生信息** @param studentsData 学生信息*/public void upDateStudents(Students studentsData) {studentsDao.update(studentsData);}/*** 查询所有学生数据*/public List searchAllStudents() {List list = studentsDao.queryBuilder().list();return list;}/*** 按条件查询数据学生信息*/public Students searchStudentsByID(int user_id) {Students studentsData = studentsDao.queryBuilder().where(StudentsDao.Properties.Id.eq(user_id)).build().unique();return studentsData;}/*** 按条件查询卡号*/public Students searchStudentsByCard(String card) {Students studentsData = studentsDao.queryBuilder().where(StudentsDao.Properties.Real_number.eq(card)).build().unique();return studentsData;}/*** 删除学生数据*/public void delete(String userId) {studentsDao.queryBuilder().where(StudentsDao.Properties.Id.eq(userId)).buildDelete().executeDeleteWithoutDetachingEntities();}/*** 清理所有学生数据*/public void deleteStudentData() {studentsDao.deleteAll();}}

每天进步一点点。。。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...