Skip to content


网络请求是 Android开发中必不可少的一部分,几乎是个app都需要请求网络获取数据。那么实现网络请求的方式是如何的呢?以及网络请求的主流方式是怎么样的呢?

HttpURLConnection

在Java中有一个原生的网络请求类**HttpURLConnection**,通过这个类可以打开一条网络请求的通道,向指定的网站发送GET请求和POST请求

groovy
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();
}

image.png
这段代码就是通过**HttpURLConnection**发起GET请求并获取到请求到的数据
但如果直接在Android的UI线程中执行网络请求,那么就会出现报错:

groovy
W/System.err: android.os.NetworkOnMainThreadException

因为Android中默认UI线程(主线程)是不能执行耗时操作的,那么要执行网络请求就必须开辟一个子线程然后执行上述的代码。
既然这样每执行一次网络请求,我们都需要开辟一个子线程,如果请求很多,我们可能还会需要一个线程池去发起网络请求。
更多详细的使用步骤详看:网络请求数据与JSON解析
其实在网络请求中必要的四个问题有:

  1. 在子线程中请求网络
  2. 多个网络请求时需要线程池维护子线程,否则频繁的线程创建和销毁会导致频繁的触发GC消耗性能
  3. 请求到的数据一般为JSON格式,如何解析
  4. 如果请求的数据需要显示在UI控件上,需要将从子线程请求到的数据切换到主线程中绑定到UI控件上

因此将这些固性的东西封装起来,让框架去帮助我们实现这些,而使用这些框架的开发者,不需要再自己开辟线程,管理线程池和解析JSON数据等。因此就有我们丰富多彩的网络请求框架啦
如今比较主流的网络请求框架就有okhttp,他是**Square **公司(美国一家移动支付公司)2013年开源的框架,至今也仍是主流。

网络请求的霸主-Okhttp

通过上面的介绍,原生**HttpURLConnection**网络请求存在如下缺点:

  1. 每次网络访问需要放在子线程里
  2. 每次得到结果需要返回到主线程才能更新控件显示
  3. 需要对各种情况进行处理,没有对状态码判断

带着这些问题,我们来看看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的优点:(每一点都可以展开讲一篇博文)

  1. 高效性能: OkHttp使用现代的HTTP/2协议来减少网络请求的延迟和提升性能。
  2. 简单易用: OkHttp提供了简单易用的API和丰富的文档,开发者可以快速上手使用。
  3. 自定义拦截器: OkHttp支持自定义拦截器,可以用于添加请求头、重定向请求、设置缓存等操作。
  4. 连接池: OkHttp使用连接池技术,可以减少网络请求的连接建立时间,提升性能。
  5. 支持异步请求: OkHttp支持异步请求,可以避免主线程阻塞,提高应用程序的响应速度。
  6. 支持缓存: OkHttp支持缓存技术,可以减少网络请求的次数,提升性能。
  7. 支持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

使用步骤

网络请求之Retrofit