一、网络的基本知识:
- 计算机网络:是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
- 计算机网络体系结构:
1、HTTP协议:
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。
HTTP协议的主要特点:
- 支持C/S(客户/服务器)模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP的消息报头:
消息报头分为通用报头、请求报头、响应报头、实体报头等。消息头由键值对组成,每行一对,关键字和值用英文冒号“:”分隔。
- 通用报头:(既可以出现在请求报头,也可以出现在响应报头中)
Date:表示消息产生的日期和时间
Connection:允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制) - 请求报头
请求报头通知服务器关于客户端求求的信息,典型的请求头有:
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
User-Agent:发送请求的浏览器类型、操作系统等信息
Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
Accept-Encoding:客户端可识别的数据编码
Accept-Language:表示浏览器所支持的语言类型
Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。 - 响应报头:(用于服务器传递自身信息的响应,常见的响应报头)
Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的
实体报头:(实体报头用来定于被传送资源的信息,既可以用于请求也可用于响应。请求和响应消息都可以传送一个实体,常见的实体报头为)
Content-Type:发送给接收者的实体正文的媒体类型
Content-Lenght:实体正文的长度
Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
Last-Modified:实体报头用于指示资源的最后修改日期和时间
Expires:实体报头给出响应过期的日期和时间
2、HTTPS协议:
HTTPS (Hyper Text Transfer Protocol over SecureSocket Layer)是以安全为目标的 HTTP 通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个系统提供了身份验证与加密通讯方法。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付等方面。
优点:
使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器。
HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
缺点:
相同网络环境下,HTTPS 协议会使页面的加载时间延长近 50%,增加 10%到 20%的耗电。此外,HTTPS 协议还会影响缓存,增加数据开销和功耗 [2] 。
HTTPS 协议的安全是有范围的,在黑客攻击、拒绝服务攻击和服务器劫持等方面几乎起不到什么作用 [2] 。
最关键的是,SSL 证书的信用链体系并不安全。特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行 [2] 。
成本增加。部署 HTTPS 后,因为 HTTPS 协议的工作要增加额外的计算资源消耗,例如 SSL 协议加密算法和 SSL 交互次数将占用一定的计算资源和服务器成本。在大规模用户访问应用的场景下,服务器需要频繁地做加密和解密操作,几乎每一个字节都需要做加解密,这就产生了服务器成本。随着云计算技术的发展,数据中心部署的服务器使用成本在规模增加后逐步下降,相对于用户访问的安全提升,其投入成本已经下降到可接受程度 [4] 。
3、HTTP与HTTPS的区别:
二、Android的网络编程:
1、Http通讯方式:
- HttpUrlConnection
在Android 2.2版本以及之前的版本使用HttpClient是较好的选择,而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择,它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。另外在Android 6.0版本中,HttpClient库被移除了,HttpURLConnection则是以后我们唯一的选择。
HttpURLConnection使用的注意事项:
1.使用setConnectTimeout()方法设置连接超时,当网络不好时,Android系统会在超过设置时间后收回资源,中断操作。
2.通过getResponseCode()对响应码进行判断,如果返回的响应码为200,则表示连接成功
3.在对大文件操作时,要将文件写到SDCard上,不要直接写到手机内存上
4.操作大文件时,要一边从网络上读取,一边往SDCard上写入,减少手机内存的使用
5.对文件流操作完毕后要及时关闭
.Android4.0后所有网络通信的操作都不能在主线程进行,需要使用独立的线程完成
Android URL通信:
HttpURLConnection访问HTTP资源的步骤:
① 根据URL地址创建URL对象
② 使用URL对象的openConnection()方法获取HttpURLConnection对象
③ 设置连接的属性,包括GET/POST请求方式
④ 输入、输出数据
⑤ 关闭输入、输出流
⑤ 在AndroidManifest配置文件中设置访问INTERNET的权限
- HttpClient
HttpClient是Apache开源组织提供的一个开源的项目,从名字上就可以看出,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接受HTTP响应。但是不会缓存服务器的响应,不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。
HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。
2、Socket通信方式:
Socket中文意思为插座的意思,专业术语称之为套接字,它把TCP/IP封装成了调用接口供开发者调用,也就是说开发者可以通过调用Socket相关API来实现网络通讯。在Java中也存在Socket相关API,主要分为两个,分别是基于UDP传输协议的Socket和基于TCP传输协议的Socket。
三、Android常用的网络编程框架:
- Volley
Google官方推出的一套小而巧的异步请求库,支持HttpClient (Android 6.0之后不再支持)、HttpURLConnection
基于网络队列,适合小数据频繁通信,请求线程池默认大小为4 - OkHttp
高性能的http库,支持同步、异步,而且支持http2、websocket协议,api简洁易用,实现了http缓存
Android网络访问的源码已用OkHttp代替了HttpURLConnection - Retrofit:
基于OkHttp封装的一套RESTful网络请求框架,底层默认采用OkHttp - 目前网络框架的最好选择:RxJava + Retrofit + OkHttp
OKHttp:
(一)OkHttp开发基本思路:
-
0kHttp的每次网络请求是一个Request,提供Request必要的参数url、header等,基于Request构造出一个Call对象,再调用它的execute()方法,就能取得Web Server回复的数据
-
如果同步调用,需要在独立的线程中执行,使用异步调用,则采用回调的方式执行,在内部封装了一个请求队列。
-
OkHttp依赖另一个组件okio完成高性能的I/O操作
-
基本用法:
- 新建一个OkHttpClient对象
- 通过Request.Builder对象新建一个Request对象
- 通过Request对象构造Call对象,调用enqueue()以异步的方式将call加入调度队列,等待request执行完成
- 通过Call对象的Callback对象返回执行结果
(二)特点:
- 0KHttp是Android版Http客户端,非常高效,支持SPDY、连接池、GZIP和 HTTP缓存。
- 默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题。
- 如果应用程序集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求。
- 从Android4.4开始,HttpURLConnection的底层实现采用了okhttp。
(三)get异步请求:
- 在另外的工作线程中执行http请求,请求时不会阻塞当前的线程,所以可以在Android主线程中使用。
- 异步请求需要加入到一个请求队列中,并且要指定回调方法。
Get方法:
private void get(String url) {
final Request request = new Request.Builder().url(url)
.header("user-agent","Mozilla/5.0(Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML,like Gecko) Chrome/51.0.2704.7 Safari/573.36")
.addHeader("Accept","application/json")
.build();
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(@NotNull Call call, @NotNull final IOException e) {
Log.e(TAG,e.getMessage());
runOnUiThread(new Runnable() {
@Override public void run() {
textView1.setText("获取失败,"+e.getMessage());
}
});
}
@Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
String json = response.body().string();
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override public void run() {
if (ip.getCode() != 0){
textView1.setText("未获得数据");
}else {
IpData data = ip.getData();
textView1.setText(data.getiP()+","+data.getArea());
}
}
});
}else {
Log.e(TAG,response.body().string());
}
}
});
}
Post方法:
private void post(String url, Map<String, String> params) {
RequestBody body = setRequestBody(params);
Request request = new Request.Builder().url(url).post(body)
.header("user-agent","Mozilla/5.0(Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML,like Gecko) Chrome/51.0.2704.7 Safari/573.36")
.addHeader("Accept","application/json")
.build();
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e("okActivity",e.getMessage());
}
@Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
String json = response.body().string();
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override public void run() {
if (ip.getCode() != 0){
textView1.setText("未获得数据");
}else {
IpData data = ip.getData();
textView1.setText(data.getiP()+","+data.getArea());
}
}
});
} else {
Log.e(TAG,response.body().string());
}
}
});
}
四、JSON数据解析:
1.概述:
- JSON:JavaScript Object Notation,最初是针对JavaScript而设计,能够很方便地在字符串和JavaScript对象中进行转换。后来成为了一种世界通用的数据交换标准,独立于具体的编程语言。
- 与XML相比,JSON语法简明,格式紧凑,易读易懂,数据传输量小,在移动互联时代,这些特点有着巨大的吸引力,因此,JSON成为了XML的替代者而被广泛应用。
2.JSON的属性值的类型:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null
3.创建JSON字符串:
当需要创建JSON字符串时,new一个JSONObject或者JSONArray对象,使用它们的put系列方法向其中追加数据,根据实际情况组合装配出JSONObject或JSONArray对象。
完成对象的装配工作之后,调用JSONObject或JSONArray的toString()方法即可生成JSON字符串
4.解析JSON字符串:
首先区分一下JSON字符串是单个对象还是数组,然后以
这个字符串作为参数,new一个JSONObject或者是JSONArray对象,Android内置的JSON解析组件就会解析JSON字符串,自动完成JSONObject或者是JSONArray对象的装配工作。
得到JSONObject或者是JSONArray对象引用之后,调用它的get系列方法,就能提取出JSON字符串中特定属性的值。