网络请求是 Android开发中必不可少的一部分,几乎是个app都需要请求网络获取数据。那么实现网络请求的方式是如何的呢?以及网络请求的主流方式是怎么样的呢?
HttpURLConnection
在Java中有一个原生的网络请求类**HttpURLConnection**
,通过这个类可以打开一条网络请求的通道,向指定的网站发送GET请求和POST请求
try {
//1.获取访问地址URL
URL url = new URL("https://www.baidu.com");
//2.创建HttpURLConnection对象
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//3.设置请求方式
urlConnection.setRequestMethod("GET");
//4.从流中读取响应数据
InputStream inputStream = urlConnection.getInputStream();// 字节流
Reader reader = new InputStreamReader(inputStream);//字符流
BufferedReader bufferedReader = new BufferedReader(reader);// 缓存流
String result = "";
String temp;
while ((temp = bufferedReader.readLine()) != null) {
result += temp;
}
System.out.println(result);
//5.关闭流
inputStream.close();
reader.close();
bufferedReader.close();
//6.关闭连接
urlConnection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
这段代码就是通过**HttpURLConnection**
发起GET请求并获取到请求到的数据
但如果直接在Android的UI线程中执行网络请求,那么就会出现报错:
W/System.err: android.os.NetworkOnMainThreadException
因为Android中默认UI线程(主线程)是不能执行耗时操作的,那么要执行网络请求就必须开辟一个子线程然后执行上述的代码。
既然这样每执行一次网络请求,我们都需要开辟一个子线程,如果请求很多,我们可能还会需要一个线程池去发起网络请求。
更多详细的使用步骤详看:网络请求数据与JSON解析
其实在网络请求中必要的四个问题有:
- 在子线程中请求网络
- 多个网络请求时需要线程池维护子线程,否则频繁的线程创建和销毁会导致频繁的触发GC消耗性能
- 请求到的数据一般为JSON格式,如何解析
- 如果请求的数据需要显示在UI控件上,需要将从子线程请求到的数据切换到主线程中绑定到UI控件上
因此将这些固性的东西封装起来,让框架去帮助我们实现这些,而使用这些框架的开发者,不需要再自己开辟线程,管理线程池和解析JSON数据等。因此就有我们丰富多彩的网络请求框架啦
如今比较主流的网络请求框架就有okhttp,他是**Square **
公司(美国一家移动支付公司)2013年开源的框架,至今也仍是主流。
网络请求的霸主-Okhttp
通过上面的介绍,原生**HttpURLConnection**
网络请求存在如下缺点:
- 每次网络访问需要放在子线程里
- 每次得到结果需要返回到主线程才能更新控件显示
- 需要对各种情况进行处理,没有对状态码判断
带着这些问题,我们来看看okhttp又做了哪些封装和优化,给开发者带来了哪些便利
使用步骤
具体使用详看:网络编程之OKHTTP框架
1、创建**OkHttpClient**
: 首先,我们需要创建一个 **OkHttpClient**
对象,这个对象会管理一些共享的资源,如:连接池、拦截器等。
2、创建 **Request**
: 接下来,我们需要创建一个 **Request**
对象,这个对象包含有请求地址、头信息、请求方法、请求体等相关内容。
3、发送请求: 使用 **OkHttpClient**
的 **newCall()**
方法创建一个 **Call**
对象,其实实际请求网络的是Call接口的真正的实现类是RealCall,通过调用 Call 的 **execute() 同步**
或者** enqueue() 异步**
方法来发送请求。怎么理解同步和异步呢?
4、处理响应: 发送请求后,**OkHttp**
会返回一个 **Response**
对象,这个对象包含有响应状态码、头信息、响应体等相关内容。
5、释放资源: 最后,我们需要释放一些资源,如:连接池、缓存等。
okhttp的优点
概述 - OkHttp (square.github.io)
由此我们可以知道okhttp框架相较于传统的网络请求的优势:
优势一:无需自己创建子线程,okhttp自动帮我们创建
优势二:返回的数据不再是数据流,而是转换好的string字符串
优势三:自动处理异常情况,提供onFailure()
方法
当然OkHttp的功能不仅仅如此,如下是okhttp的优点:(每一点都可以展开讲一篇博文)
- 高效性能: OkHttp使用现代的HTTP/2协议来减少网络请求的延迟和提升性能。
- 简单易用: OkHttp提供了简单易用的API和丰富的文档,开发者可以快速上手使用。
- 自定义拦截器: OkHttp支持自定义拦截器,可以用于添加请求头、重定向请求、设置缓存等操作。
- 连接池: OkHttp使用连接池技术,可以减少网络请求的连接建立时间,提升性能。
- 支持异步请求: OkHttp支持异步请求,可以避免主线程阻塞,提高应用程序的响应速度。
- 支持缓存: OkHttp支持缓存技术,可以减少网络请求的次数,提升性能。
- 支持HTTPS: OkHttp支持HTTPS协议,可以保证数据传输的安全性。
OkHttp 适用于 Android 5.0+(API 级别 21+)和 Java 8+。
Okhttp的Plus版-Retrofit
为什么称retrofit是okhttp的plus版呢?
因为:Retrofit
是对http网络请求框架的封装,一般由okhttp
来负责网络请求,retrofit
对请求接口进行封装。retrofit
通过接口和注解来描述我们的网络请求,然后通过client
去调用okhttp
框架,通过addConverterFactory
来实现对返回的json数据进行处理,转换成我们需要的数据类型,可以理解为okhttp的加强版,底层封装了Okhttp。