Android智能穿戴设备开发实战详解
上QQ阅读APP看书,第一时间看更新

4.1 实现网络通信的解决方案

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。在本节的内容中,首先简要介绍HTTP技术的相关基本理论知识,为读者步入本书后面知识的学习打下基础。

4.1.1 剖析HTTP的作用

HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其他工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。我们称这个客户端为用户代理(user agent)。应答的服务器上存储着(一些)资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(Origin Server)。在用户代理和源服务器中间可能存在多个中间层,比如代理,网关或者隧道(Tunnels)。尽管TCP/IP协议是互联网中最流行的应用,HTTP协议并没有规定必须使用它和基于它支持的层。事实上,HTTP可以在任何其他互联网协议上或者在其他网络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使用。

通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认端口为80)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器(向客户端)发回一个状态行,例如“HTTP/1.1 200 OK”和响应的消息,消息的消息体可能是请求的文件、错误消息、或者其他信息。

HTTP使用TCP而不是UDP的原因在于打开一个网页必须传送很多数据,而TCP协议提供传输控制,按顺序组织数据和进行错误纠正。

HTTP是超文本传输协议,是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。HTTP包含命令和传输信息,不仅可用于Web访问,也可以用于其他因特网/内联网应用系统之间的通信,从而实现各类应用资源超媒体访问的集成。

当想浏览一个网站时,只要在浏览器的地址栏里输入网站的地址即可,例如www.*****.com,但是在浏览器的地址栏里面出现的却是:hhttp://www.*******,读者知道为什么会多出一个“http”吗?

在浏览器的地址栏里输入的网站地址称作URL(Uniform Resource Locator,统一资源定位符)。就像每家每户都有一个门牌地址一样,每个网页也都有一个Internet地址。当在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成漂亮的网页。因此在认识HTTP之前,有必要先弄清楚URL的组成。例如:hhttp://www.******.com/china/index.htm,它的含义如下所示。

(1)hhttp://:代表超文本转移协议,通知****.com服务器显示Web页,通常不用输入。

(2)www:代表一个Web(万维网)服务器。

(3)****.com/:这是装有网页的服务器的域名,或站点服务器的名称。

(4)China/:为该服务器上的子目录,就好像我们的文件夹。

(5)Index.htm:index.htm是文件夹中的一个HTML文件(网页)。

众所周知,Internet的基本协议是TCP/IP协议,然而在TCP/IP模型最上层的是应用层(Application layer),它包含所有高层的协议。高层协议有:文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和HTTP协议等。

4.1.2 Apache接口和标准Java接口的区别

因为在Android平台中,使用的最多的是Apache接口。在Apache HttpClient库中,以下内容为对网络连接有用的各种包。

● org.apache.http.HttpResponse。

● org.apache.http.client.HttpClient。

● org.apache.http.client.methods.HttpGet。

● org.apache.http.impl.client.DefaultHttpClient。

● HttpClient httpclient=new DefaultHttpClient()。

Apache的核心功能是HttpClient,和网络有关的功能几乎都需要用HttpClient来实现。在Android开发中经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便使用各种HTTP服务。你可以把HttpClient想象成一个浏览器,通过它的API可以很方便的发出GET请求和POST请求。

例如只需要以下几行代码就能发出一个简单的GET请求并打印响应结果。

肯定有读者禁不住要问为什么上述代码要使用单例HttpClient呢?这只是一段演示代码,实际的项目中的请求与响应处理会复杂一些,并且还要考虑到代码的容错性,但是这并不是本篇的重点。读者重点注意代码的第三行:

在发出HTTP请求前先创建了一个HttpClient对象,而在实际项目中,我们很可能在多处需要进行HTTP通信,这时不需要为每个请求都创建一个新的HttpClient。因为之前已经提到,HttpClient就像一个小型的浏览器,对于整个应用,只需要一个HttpClient即可。由此可以得出,使用简单的单例即可实现,例如下面的代码。

但是如果同时有多个请求需要处理呢?答案是使用多线程。假如现在应用程序使用同一个HttpClient来管理所有的HTTP请求,一旦出现并发出请求,那么一定会出现多线程的问题。这就好像浏览器只有一个标签页却有多个用户,A要上谷歌,B要上百度,这时浏览器就会忙不过来。幸运的是,HttpClient提供了创建线程安全对象的API,帮助我们能很快地得到线程安全的“浏览器”。

4.1.3 Android独有的网络接口

在Android平台中,可以使用Android网络接口android.net.http来处理HTTP请求。android.net.http是android.net中的一个包,在里面主要包含处理SSL证书的类。在android.net.http中存在如下四个类。

● AndroidHttpClient。

● SslCertificate。

● SslCertificate.DName。

● SslError。

其中AndroidHttpClient就是用来处理HTTP请求的。

android.net.*实际上是通过对Apache的HttpClient的封装来实现的一个HTTP编程接口,同时还提供了HTTP请求队列管理,以及HTTP连接池管理,以提高并发出请求的情况下(如转载网页时)的处理效率,除此之外还有网络状态监视等接口。

4.1.4 在屏幕中传递HTTP参数的实现技巧

经过前面的学习,了解到HTTP是一种网络传输协议,现实中的大多数网页都是通过“HTTP://WWW.”的形式实现显示的。在具体应用时,一些需要的数据都是通过其参数传递的。和网络HTTP有关的是HTTP protocol,在Android SDK中,集成了Apache的HttpClient模块。通过这些模块,可以方便的编写出和HTTP有关的程序。在Android SDK中通常使用HttpClient 4.0。在下面的实例中插入了两个按钮,一个用于以POST方式获取网站数据,另外一个用于以GET方式获取数据,并以TextView对象来显示由服务器端的返回网页内容来显示连接结果。当然首先得建立和HTTP的连接,连接之后才能获取Web Server返回的结果。

编写文件httpSHI.java,其具体实现流程如下所示。

● 引用apache.http相关类实现HTTP联机,然后引用java.io与java.util相关类来读写档案。

● 使用OnClickListener来聆听单击第一个按钮事件,声明网址字符串并使用建立Post方式联机,最后通过mTextView1.setText输出提示字符。具体代码如下所示。

● 使用OnClickListener来聆听单击第二个按钮的事件,声明网址字符串并建立Get方式的联机功能,分别实现发出HTTP获取请求、获取应答字符串和删除冗余字符操作,最后通过mTextView1.setText输出提示字符。具体代码如下所示。

● 定义替换字符串函数eregi_replace来替换掉一些非法字符,具体代码如下所示。

在文件AndroidManifest.xml中声明网络连接权限,具体代码如下所示。

执行后的效果如图4-1所示,单击图中的按钮能够以不同的方式获取HTTP参数。

图4-1 单击“使用POST方式”按钮后的效果

4.1.5 如何在运动过程中访问地图

在使用智能穿戴设备的过程中,经常需要远程服务器的信息。例如,作为一名户外“驴友”成员,为了确保自己行走的路程准确无误,可以随时访问服务器中的地图来进行对照。在下面的实例中,以一名户外“驴友”使用穿戴设备为背景,讲解了在Android穿戴设备中使用HTTP访问服务器中地图的过程。

在下面的实例中首先创建了HttpGet和HttpPost对象,并将要请求的URL对象构造方法传入HttpGet、HttpPost对象中。然后通过HttpClent接口的实现类DefaultClent的excute(HttpUriRequest request)方法实现连接处理。因为已经知道HttpGet和HttpPost类都实现了HttpUriRequest接口,所以可以将前面创建好的HttpGet或者HttpPost对象传入以得到HttpResponse对象。最后通过HttpResponse获取返回的HTTP资源信息,然后再做提取工作。

本实例的具体实现流程如下所示。

(1)编写核心文件HTTPDemoActivity.java,根据EditText控件中的输入的数据来访问远程HTTP资源,并将得到的信息转换成一个输出流并返回。在整个实现过程中需要通过url创建HttpGet对象,并通过DefaultClient的excute方法返回一个HttpResponse对象。文件HTTP-DemoActivity.java的主要实现代码如下所示。

(2)在设置文件AndroidManifest.xml中添加访问网络资源的权限,具体代码如下所示。

(3)设置一个Java服务器环境,在里面添加服务器资源供前面的Android客户端来访问。将光盘中的源码的“Servers”部分复制到本地Java服务器的Tomcat中。

最终客户端的执行效果如图4-2所示。

图4-2 获取服务器中的箭扣长城徒步活动路线图