第6章已经讨论过和远程服务交互的用户接口所面临的一些大的挑战,例如UI线程中不要绑定运行时间较长的任务。第3章还探讨过Android的内容提供者API共享方式和REST风格的Web服务间的对应关系。内容提供者的数据操作可以直接映射到REST风格的数据操作,本章将介绍如何使用内容提供者的URI来请求网络数据。建议充分利用这种对应优势,在实现内容提供者时,把它作为位于应用和需要从应用获取数据的网络请求之间的异步缓冲区。使用这种方式编写的应用会简化,而且可以规避掉在Android和其他Java编程中遇到的一些常见的UI和网络编程错误。
一般而言,Java UI编程人员,无论是对企业应用还是移动应用,编写的移动和桌面应用都过于脆弱,有时直接在UI线程上执行了网络请求,而且通常情况下还没有缓存这些请求所获取到的数据。在大多数应用中,每次用户请求时,在UI上显示的所有数据都需要通过网络来获取。信不信由你,在20世纪80年代和90年代,当远程的文件系统不可用时,UNIX工作站经常僵死。如果采用了本地动态缓存机制,那么在无法访问远程文件系统时,这些工作站理应还可以继续运行,在可以访问时再执行数据同步。开发人员需要在潜意识中就注意确保其应用能够正确地访问和存储网络数据。
在J2ME中依然存在这个问题,开发人员会把网络状态缓存到名为RMS的记录管理系统中,该RMS库不支持查询,也不支持MVC通知机制。J2ME开发人员需要扩展自己的纯Java线程,添加对网络请求的支持,这通常导致应用很脆弱。如果Web浏览器需要在UI线程上加载网络数据,你会发现当因网络挂掉而导致UI线程被锁定时,该Web浏览器就完全僵死了,必须由操作系统杀死这个进程才能退出。浏览器所显示的页面和所有图片在每次用户查看时都需要重新下载,这使得用户体验非常差——假定请求没有导致整个应用挂掉。造成这种现象的一个原因是,操作系统通常把对网络数据的加载和缓存工作全部留给应用本身,只提供很少的库来帮助开发人员正确地实现这些任务。
要解决这些问题,可以使用完全异步的接口来处理网络交互和数据存储。通过这种方式,开发人员必须要思考什么时候可以请求网络数据——在UI线程上使用该API是否都是安全的。在移动环境中,这种思想变得更加重要,因为间歇性的网络连接增加了不良代码被挂起的可能性。
建议使用内容提供者API作为网络的异步模型,缓存网络状态,这样应用的视图和控制器不需要自己的打开连接或访问数据库机制。可以很简单地把provider的API映射到已有的基于REST的Web服务的API——提供者只是作为应用间的桥梁,把请求转发到网络,并缓存需要的结果。本章将说明这种方式会如何简化应用,并解释这种技术的更多优势,包括它如何把Web和AJAX编程的一些良好的特性结合到Android应用中。关于AJAX编程的更多信息,可参考http://en.wikipedia.org/wiki/Ajax_(programming)。