【绝非标题党】Android 如何优化网络请求


在 Android 应用开发中,网络请求的性能直接影响用户体验。 优化网络请求不仅可以提升应用的响应速度,还能降低资源消耗,也是高频面试题。最近面试的时候也被问到了这个问题,固做一个总结,供自己学习,希望也对你有所帮助,也欢迎有不同想法的提出富贵的看法。


总结下来可以从以下几方面进行优化:

  • 使用高效的网络库
  • 实现连接池管理
  • 压缩数据传输
  • 实施缓存策略
  • 优化 DNS 解析

使用高效的网络库


选择合适的网络库可以简化开发并提升性能。 例如,OkHttp 是一个高效、稳定的 HTTP 客户端,支持连接池、GZIP 压缩和缓存等功能,有助于减少网络延迟和数据流量

实现连接池管理


连接池的作用

每次建立新的网络连接(例如 TCP 连接)都需要经历握手过程,这不仅增加了延迟,还消耗系统资源。 连接池通过维护一组已经建立的连接,允许后续的网络请求复用这些连接,避免重复的握手过程,从而提高效率。

因为每一步的 网络请求需要经过三次握手,四次挥手,这是一个耗时的操作,连接池能大大缩短网络请求的时候

压缩数据传输


在 Android 开发中,为了减少网络传输的数据量,提高应用性能,通常会对数据进行压缩后再传输。 以下是实现数据压缩传输的主要方法: 在 Android 开发中,为了减少网络传输的数据量,提高应用性能,通常会对数据进行压缩后再传输。以下是实现数据压缩传输的主要方法:

1. 使用 Gzip 压缩

步骤

css 复制代码
客户端发送请求时,声明支持 Gzip 压缩
在 HTTP 请求头中添加 Accept-Encoding: gzip,表示客户端能够接受 Gzip 压缩的数据。
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
 connection.setRequestProperty("Accept-Encoding", "gzip");

2 服务器端响应数据时,进行 Gzip 压缩 :
服务器检测到客户端支持 Gzip 后,对响应数据进行 Gzip 压缩,并在响应头中添加 Content-Encoding: gzip。 3 客户端接收响应时,判断并解压缩:
客户端检查响应头中的 Content-Encoding 是否为 gzip,如果是,则使用 GzipInputStream 对数据进行解压缩。

InputStream 复制代码
String encoding = connection.getContentEncoding();
 if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
    inputStream = new GZIPInputStream(inputStream);
 }

实施缓存策略


  1. cache-control

减少网络请求:

  • 当客户端收到包含 Cache-Control 的响应后,会将响应数据缓存在本地。
  • 在缓存有效期内,如果客户端再次请求相同的资源,它可以直接从本地缓存中获取数据,而无需再次向服务器发送请求。
  • 这大大减少了网络延迟,提高了响应速度。
  1. etag

原理:

  • 后端接口在 response-header 返回 etag 值,并在客户端缓存这个值
  • 在下一次请求的时候,在 request-header中,将 etag 值放在 if-none-match 中值传给服务端
  • 服务端会将请求头里面的 etag值,与当前服务端的 etag 值进行匹配,如果匹配上,则直接返回 http 响应码 304,不返回响应数据, 客户端则直接使用上一次缓存的数据

Etag 的性能优化效果: 减少带宽消耗:

  • 当资源没有发生变化时,客户端只需要下载一个很小的HTTP 304响应,而不是整个资源内容。
  • 这大大减少了网络带宽的消耗。

提高响应速度:

  • 由于客户端可以直接使用本地缓存,无需等待服务器返回完整的响应,因此响应速度更快。

减轻服务器负载:

  • 当大量客户端请求未修改的资源时,服务器只需要返回简单的HTTP 304响应,而不是处理复杂的资源生成和传输。
  • 这减轻了服务器的负载。

优化 DNS 解析


DNS 解析耗时可能导致网络延迟。 使用 HTTPDNS 等技术可以避免本地 DNS 劫持,减少解析时间,提高网络请求的可靠性和速度。

java 复制代码
import okhttp3.Dns;
import okhttp3.OkHttpClient;
import java.net.InetAddress;
import java.util.List;

// 创建自定义的 DNS 解析器
Dns customDns = new Dns() {
    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        // 使用 HTTPDNS 解析域名
        String ip = httpDns.getIpByHostAsync(hostname);
        if (ip != null) {
            return Arrays.asList(InetAddress.getAllByName(ip));
        }
        // 如果 HTTPDNS 解析失败,使用系统默认解析
        return Dns.SYSTEM.lookup(hostname);
    }
};

// 配置 OkHttpClient 使用自定义的 DNS 解析器
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .dns(customDns)
        .build();

CDN


CDN 能根据用户的地理位置、网络状况等因素,智能选择最优路径,确保数据传输的稳定性和速度

相关推荐
在下木子生6 分钟前
mac如何将jar包上传到maven中央仓库中
java·macos·maven·jar
写代码的小王吧25 分钟前
【网络安全】 防火墙技术
java·python·安全·web安全·网络安全·docker
XiaoLeisj26 分钟前
【MyBatis】深入解析 MyBatis:关于注解和 XML 的 MyBatis 开发方案下字段名不一致的的查询映射解决方案
xml·java·spring boot·spring·java-ee·tomcat·mybatis
信徒_39 分钟前
Spring 中有哪些设计模式?
java·spring·设计模式
爱的叹息1 小时前
关于 Spring自定义缓存管理器 的详细说明,包含两种实现方式的对比和代码示例,并附表格总结
java·spring·缓存
刘龙超1 小时前
如何应对 Android 面试官 -> 网络如何优化?
android·java
IT瘾君1 小时前
Java基础:Logback日志框架
java·开发语言·logback
suimeng61 小时前
Java的Selenium的特殊元素操作与定位之select下拉框
java·自动化测试·selenium
ChinaRainbowSea1 小时前
8. RabbitMQ 消息队列 + 结合配合 Spring Boot 框架实现 “发布确认” 的功能
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
、BeYourself2 小时前
Sentinel[超详细讲解]-7 -之 -熔断降级[异常比例阈值]
java·spring cloud·sentinel