Android性能优化之关于缓存的构思

为了提升用户体验, 对应用显示的数据进行缓存是非常好的方案.用过ListView,GridView,ViewPager等这些组件的童鞋都知道 , 应用都有预加载的行为, 比如当前看的是ViewPager第一页数据, 第二页甚至第三页还没显示出来, 但数据已经准备就绪, 用户只要一滑动到下一页, 数据马上就显示, 而不是等到滑动第二页才去加载(当然有时候为了优化,也可能这么做吧,具体情况具体分析.). 这是一种情况. 


那么另一种情况是, 将某个页面使用过的数据缓存下来(一般是放在本地), 当下次再打开该页面, 就马上加载旧的数据. 如果应用需要最新的数据, 这时就后台访问服务器获取数据,然后更新, 把旧数据替换掉. 


上面2种情况都是缓存的行为.通过缓存我们为不但最快的将完整的页面呈现给用户, 也为应用争取处理更多任务的机会,提高效率.


缓存的方式有哪些,怎么选择?

1, 首当其冲, 当然是应用级的缓存 - 运行内存. 

效率最高, 但这个内存大小非常有限, 多则几十兆, 少则几兆, 因机型的配置参数而异.  因此可供使用的缓存也不多,只能将体积小, 数量有限且频繁被使用的数据进行缓存.比如头像,应用内到处用到的小的图片素材等等都能适当的存入内存中.这样能避免针对同一个对象频繁访问本地存储获取.


2, 数据库. 

Android自带的SQLite是一种轻量化, 效率高的数据库.支持SQL语句. 支持百万级的数据存储量. 适合存放字符文本这类的数据. 比如常见的字典, 新闻内容, 景点介绍, 气象数据等等. 但是频繁并发的在数据库进行存取是一个问题,这个不得不考虑. 比如将批量的insert 操作包装成一个事务, 避免重复访问存储磁盘, 是很好的选择.  又或者优化查询语句等等.


3, 文件(File)的形式.

Java中几乎所有流(stream)的东西都能变成File的形式保存下来. 图片,文字,安装包等, 甚至对象, 都能保存成File. Java是支持序列化的, 实现序列化接口的对象就能传递和保存. 图片保存的方式, 当然是常见的JPG, PNG. 但是很多新闻应用,你会发现, 这些应用明明缓存了图片, 却在本地找不到. 其实他们为了避免被一些扫描应用"看到", 都会以自定义的后缀所保存在本地. 本质还是一张图片, 后缀就不是JPG, PNG了. 但这丝毫不影响应用在使用时对图片进行File读取和使用.


4, SharePreference.

SharePreference 是Android提供的一种轻量化的以XML文件格式进行本地存储的方式.因此, 系统提供了便捷的接口调用, 类似MAP的KEY - VALUE格式, 不用写复杂的存储过程,直接进行PUT和GET操作即可对数据进行存储和读取. SharePreference 并不适合存储复杂的数据.


5, 网络.

有些数据, 基于安全, 体积或者其他的考虑, 不适合存储在本地, 应该避免被非本应用用户"看到"的, 可以考虑存放在服务器. 因为网络数据的传输过程经过加密, 甚至还有另外约定的加密解密规则, 将这么保密的工作交给后台是最适合不过. 最经典的莫过于, 我们常用的网盘. 手机上传任何文件到网盘, 这些文件肯定不是放在本地, 而是加密放在网上专门的存储空间. 只有个人用户登录服务器才能查看自己上传的文件, 除非分享给第三方. 手机只负责按约定的规则上传, 至于上传存储后怎么保存就漠不关心了.


6, 其他.

比如ContentProvider, 通过应用间的共享机制去获取或分享数据. 但较少应用会主动共享自己的应用数据, 所以比较少用到.


可供考虑的几个点:

通过上面的介绍, 我们知道几种缓存的方式和各自的特点. 优化的产品,肯定不仅限于一种或少数几种的优化策略, 而是全面推进或由点至面, 从浅而深的过程. 同样选择缓存的策略, 也不能满足于一种或少数几种方式. 应该根据具体的场景去选择对应的方式缓存, 最好考虑以下几个点(根据个人理解, 仅供参考):


1, 数据读写过程的效率, 这里又包括, 比如数据的体积大小, 数据的类型, 数据的来源, 数据的去向(用在哪里)等等.


应用中常见的数据,最主要就是图片和文字.所以这里也针对这两者展开一些观点. 比如图片, 存在应用缓存中肯定不合适, 而且大图首先考虑压缩策略, 经过一定比例的压缩, 然后转换成File, 存储在本地.对于少数图片, 不希望图片被随便删除什么的, 可以考虑将图片通过二进制转码存进数据库. 有些新闻的应用也这么实现. 如果图片的数量较多, 则不推荐这种方式了, 因为图片转码存储的效率并不很高. 在这里, 我们考虑了数据的类型和体积.


如果是小图, 只有一百几十KB呢, 如果数量较多呢? 我们就会想优先通过File的形式将图片存在本地, 觉得这样效率还是可观的. 但如果这些小图的去向是不只是呈现在当前的手机端, 而且希望在其他手机端和PC网页也能看到, 比如发一条微博, 发布一条带图片的新闻, 就不得不需要上传到服务器, 由后台实现共享. 这时将图片存在本地就没多少必要了.  OK, 如果不是图片, 是文字怎么办?  一般情况下,如果这些文字是有机会还会被阅读的,有价值的, 比如新闻资讯的内容, 那就能存多少存多少吧. 这种情况下, 首选数据库.


谈到数据的来源, 如果应用有"设置"选项, 而用户希望通过一次设定, 应用就能"记住"自己的使用习惯, 比如夜间模式, 是否自动加载下一页, 无图模式, 用户的一些配置信息等等, 针对这些"配置"类的信息, 它们来自应用的本身, 而且不需要在服务器呈现(除非客户端和后台保持一致性, 用户希望将这种习惯带到PC或平板上等等, 就需要将这些信息上传到服务器保存起来.),  而且这些信息也不算宝贵, 适合选择SharePreference这类Key - Value的缓存方式, 当然数据库也行.


2, 数据的时效性.


不同的数据, 时效性可能就不一样了. 比如广告和新闻. 很多应用都有广告, 这些广告的某些数据也可能存在本地. 但每次打开应用, 一连接网络, 广告就会自动刷新,下载最新的数据来展示广告.对于这种经常需要自动刷新的数据, 大可不必缓存在本地, 或者不必全部缓存在本地, 一是占用空间, 二是没多少时效性.  在这方面更明显的, 就是评论类的数据信息. 流行的"盖楼文化" 使得一些热门资讯后面跟着成千上万条的评论, 每次打开相同的新闻, 我们又希望这些评论能最快的展示出来, 又希望这些评论是最新的, 无论手机还是PC上网的用户都能看到最新的评论信息, 是否有人回复自己等等. 这是不得不选择两者结合, 比如将部分的评论信息缓存在数据库, 同时通过网络调用服务器提供的最新数据来刷新旧数据.


3, 数据的可维护性.


很简单, 一条新闻的文本信息,如果转换成text File存在本地, 那么每次更新这条新闻都需要进行一次File的保存操作. 相对于将这条数据放在数据库, 通过表的update操作更新文本内容. 前者的可维护性明显低于后者.


4, 数据的安全性.


有数据的地方, 就必须考虑安全性. 谁也不能否定用户登录的账户密码的重要性高于哪怕很好看的应用本身. 对于账户密码等私密性较高或容易成为偷窃目标的数据, 首先是不适合明文保存的方式, 也不适合共享, 所以类似ContentProvider的共享, 肯定是没人用在这里的. 实在要放在本地的话, 那放在数据库还是SharePreference? 一般而言, 数据库优于SharePreference, 但如果你已拥有自己独特的加密规则, 就算明文COPY出来也只有你才懂解密. 好吧, 你赢了.


其实撇开账户密码这些老生常谈, 我们在很多应用场景都不得不考虑数据的安全性, 比如电子支付, 通讯录的联系方式, 重要人物的相关资料, 一些重要的文档资料等等, 这些规则或不规则的重要的数据, 首选通过网络存储在服务器. 尽量不缓存在本地. 服务器的安保性肯定高于应用.即便手机被盗也能通过关联的账户登录服务器管理这些敏感的数据. 很明显, "云"已成为一种主流.越来越多的数据,都放在"云"端. 以前将数据放在手机, 手机不见了就什么都没了,怎么保护数据是自己的事儿, 但现在数据放在云, 手机没了数据还在, 安全价值高的数据也还妥妥的. 因为不再是自己一个人, 背后有一众维护服务器的技术人员专门在从事这个.  额, 有点扯远了. 本文就到这里了. 感谢你的阅读.



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。