Android性能优化之解密ZAKER,网易云阅读等新闻应用的内容缓存加

我是比较关注时事的, 每天都会花一点事件去看看新闻什么的. 因此类似ZAKER, 网易云阅读等这类的资讯聚合类应用是我的钟爱, 并且这些应用也确实做得很好,值得学习!前面一篇文章, 讲了缓存的一些构思. 之前也写过LRUCache类的一些缓存实践, 但那只是放在应用的缓存中,并不适合做长期的缓存. 这次我们来实践完整的例子, 模仿ZAKER那类应用是如何加载一条新闻的,并且如何缓存这条新闻的.

写在前面, 本篇文章只是其中一种实现方式, 仅为阐述思路, 并不代表最优的做法. 条条大路通罗马嘛.

实现效果

效果图( 如果打不开, 请复制图片地址到地址栏打开. 源码在文章底部. )

先说效果, 实际使用中, 当用户第一次打开一条新闻, 这条新闻出来的是文字, 然后显示默认加载中的图片, 用户慢慢的滑动屏幕浏览新闻, 同时新闻中的图片也慢慢的加载出来, 做的更人性化的, 甚至会将加载中的图片都显示百分比或者进度信息, 让用户知道这张图片大概还差多少就加载完毕. 然后退出当前的页面, 点击别的标题, 继续看别的新闻… 一直重复这个操作.

当因为某些原因, 网络关闭了, 但用户无聊, 在公交上想看看之前浏览过的新闻, 但为了省流量关闭了手机网络而且公交上没有WIFI. 用户打开应用, 点开之前看过的新闻标题, 进入依然能看到之前的完整的新闻, 图片文字什么都有.

到了这里, 我们应该明白, 用户看过的新闻文字和图片都缓存在本地了.上篇文章写过, 图片一般适合通过File缓存在本地, 大篇的文字适合放在数据库. 没错, 就这么实现~

接下来希望将具体的思路说清楚, 那么自己实现起来,或者看下面的示例代码, 都能有更好的理解.

具体的思路1, 如何实现

ZAKER的新闻显示, 是使用WebView做载体, 然后使用自定义的HTML模版, 将服务器传递到客户端的数据填充本地的HTML模版去显示. 好看的HTML模版, 包含不少通用的CSS, JS, 是一个优秀前端开发人员的产品, 作为移动开发, 我们并不需要在这方面了解太多. 如果有需要, 大可叫公司的前端开发人员提供对应的模板. 所以我们下面的例子, 只是简单的HTML模板, 方便阐述原理.

1) 在服务器获取用于填充HTML模板的一条新闻内容的数据后, 我们还应当得到这条新闻所包含的图片信息, 比如图片名字, 图片id, 图片的下载链接等等… 将文字内容存入数据库.

2) 然后通过一些方法( 一般是JavaScript) 在WebView的页面控制 先显示文字,和加载中的默认图片. 同时在本地新建线程去下载这些图片.

3) 每有一张图片下载完成, 就将图片存入本地存储空间中. 并且将图片的信息放入数据库或其他地方. 这样以后要用这张图片, 直接用图片的下载链接作为查询条件, 先去数据库查找, 如果存在, 就获取该图片下载链接所对应的本地存储路径信息. 如果路径有效则使用, 无效或查找无果, 则重新下载.

4) 上面下载完一张图片后还没结束, 最后, 每下载完一张图片, 还要在WebView中将默认的图片替换成所下载的图片. 整个过程大致如此.

2, 需要一点别的知识 -JavaScript

看了上面四个步骤, 相信在从服务器获取数据, 对数据库SQLite进行存取数据, WebView加载HTML源码等等这些是毫无难度的. 但有一些地方,确实本地代码很难完成的, 需要借助JavaScript. WebView是支持JavaScript的,因为它能完成很多页面的工作, 比如监听WebView的网页滚动坐标, 控制页面滚动等常见的场景, 类似网页开发的 lazyload( 延迟加载图片, 异步加载图片等 ) 效果都借助了js实现. 而且JavaScript还能和本地代码进行交互被调用, 使得WebView变得异常强大. 比如上面的图片异步加载( 先显示默认图片, 然后图片下载完去替换默认图片 ), 在页面获取图片信息, 调用本地代码去下载图片等, 这些都是实现的关键地方, 依靠JavaScript完成.

但是要注意,JavaScript是容易产生安全漏洞的地方, 稍有不慎,就会成为被攻击的入口. 所以不建议随意去用.

说了上面一堆, 应该不难理解我们接下来所要实现的功能了吧.但有几个地方, 在这里进行说明:

1, WebView是可以直接加载本地资源的, 比如SD卡, assets, raw等文件夹里的都可以.

2, 多线程使用数据库, 比如SQLite. 必须注意并发同步等问题. 对于不是高并发, 线程数也不多的, 最简单的可以用关键字synchronized去解决. 不然很容易抛错.

3, 图片保存和读取,要注意文件的体积大小. 具体应用中,推荐的方案是服务器已经根据移动端对图片进行了压缩优化再传递, 这样客户端可以降低处理的复杂度.

设想一下, 有限大小的屏幕中, 一堆文字不占什么空间流量, 但却给了几张原图大小的图片过来, 是毫无意义的. 内容中显示小图, 如果用户点击图片弹出, 或者 点击保存原图, 这时才另外下载原图, 既保证交互的舒适感, 也保证流量和性能都没有被浪费.

So 直接上代码, 结合代码的注释和上面的说明, 就容易理解多了.

先是用到的2个页面的简单XML,

activity_main.xml

<RelativeLayout xmlns:android=""xmlns:tools=""android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.alextam.webviewdemo.MainActivity"tools:ignore="MergeRootFrame"><TextViewandroid:layout_width="match_parent"android:layout_height="50dp"android:background="#88888888"android:text="测试WebView缓存"android:textColor="#FFFFFFFF"android:textSize="18sp"android:gravity="center"android:layout_alignParentTop="true"/><Buttonandroid:id="@+id/btn_start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="20dp"android:text="打开页面"android:layout_centerInParent="true"/></RelativeLayout>

享受每一刻的感觉,欣赏每一处的风景,这就是人生。

Android性能优化之解密ZAKER,网易云阅读等新闻应用的内容缓存加

相关文章:

你感兴趣的文章:

标签云: