假如要实现一个功能,手机上存储有一百万首诗,如存在数据库或者文件之类,要把它们显示在列表上。
为了方便,每首诗的内容我都写成一样:
初步实现方案:
用最直接简单的实现,界面是一个RecyclerView
先定义一个类放数据:
然后把全部数据从手机上读取出来,为了方便就不写那么多,我这是模拟把数据库的内容读到内存里:
,放入Adapter设置给RecyclerView,运行一下,没问题,效果如下:
界面看上去是没有问题的,然后打开AS的Profiler,看下内存里面的数据:
可以看到,app总共占用了122.5M的内存,Java分配的对象占用内存是24.9M,并且在下方可以看到,在虚拟机堆里面,存有一百万的数据的ListItem对象是最多的,达到了1600 0000字节,约15m,60%多。可见ListItem占用了大量的内存。
内存优化方案:
由于ListItem占用了大量的内存,可以以此作为一个优化点,在RecyclerView显示界面上,只能显示有限几个的数据,我们并不需要一下子把所有数据都全部加载到内存里,可以按需加载,当列表滑动到某个位置时,再从手机存储里面加载数据出来。
因此,假如这一百万首诗都存储再数据库里面,利用Cursor的moveToPosition方法,可以实现一个按需加载的功能。首先定义一个可以利用Cursor加载数据的Adapter:CursorRecyclerViewAdapter,其中核心代码就是:
用户滑动到哪个位置就利用Cursor移到那个位置去加载那个位置的数据,这样就不用把全部数据加载进内存了,运行一下,再利用Profiler看下内存占用情况:
这时:app总共占用了57.1M的内存,Java分配的对象占用内存是9.1M,并且ListItem占用的内存已经可以忽略不计了,省下了大量的内存,并且同样实现了显示一百万条数据的功能。
对象复用优化:
上面代码中,从Cursor加载出数据的代码是:
里面new了一个ListItem,假如快速滑动时,就会迅速产生大量短生命周期的对象,看下Profiler的内存情况:
从第一幅图可以看到,有锯齿状出现,并且ListItem达到了542个,可见,快速滑动时,短周期的对象大量产生。
帧率优化方案:
还可以怎么优化吗,再使用另一个工具测试下,企鹅的调试工具GT。
待续。。。