1. Android网络请求面试核心要点解析
作为Android开发中的基础能力,网络请求模块的掌握程度直接影响着应用性能和用户体验。在面试中,这既是必考题也是区分候选人水平的关键指标。我从面试官角度整理了网络请求的完整知识体系,包含高频考点和实战技巧。
1.1 基础框架选择与对比
目前主流网络库主要有三种选型方案:
- HttpURLConnection:JDK原生方案,需要手动处理线程切换和解析逻辑。适合学习网络原理的场景,但生产环境效率较低。典型代码结构如下:
java复制HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
-
Volley:Google推出的轻量级库,适合数据量小、频繁请求的场景。其特点包括:
- 自动调度网络请求
- 默认磁盘和内存缓存
- 不支持大文件下载
- 已停止官方维护
-
OkHttp + Retrofit:当前业界主流方案组合:
- OkHttp处理底层通信(HTTP/2支持、连接池、GZIP压缩)
- Retrofit负责接口封装(通过注解配置请求)
- 支持RxJava/Coroutine等异步方案
实际项目中建议直接采用OkHttp+Retrofit组合,既能满足复杂需求又便于维护扩展。Volley仅适合遗留项目维护,新项目不建议采用。
1.2 高阶功能实现方案
1.2.1 多级缓存策略
完整的缓存体系应包含:
- 内存缓存:使用LruCache实现,响应速度最快
- 磁盘缓存:通过OkHttp的CacheControl配置
- 网络请求:最终数据来源
配置示例:
java复制// 内存缓存(20MB容量)
LruCache<String, Bitmap> memoryCache = new LruCache<>(20 * 1024 * 1024);
// 磁盘缓存(50MB容量)
Cache cache = new Cache(context.getCacheDir(), 50 * 1024 * 1024);
OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();
1.2.2 文件上传下载
大文件传输需要特殊处理:
- 上传使用MultipartBody.Builder构造表单数据
- 下载通过拦截器实现进度回调:
java复制public class ProgressInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), progressListener))
.build();
}
}
1.2.3 网络状态监控
通过ConnectivityManager检测网络变化:
java复制ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
1.3 性能优化关键点
-
连接池配置:
java复制new OkHttpClient.Builder() .connectionPool(new ConnectionPool(5, 10, TimeUnit.MINUTES))- 最大空闲连接数:5
- 保持时间:10分钟
-
请求合并:
- 使用GraphQL减少请求次数
- 批量接口设计(如/api/users?ids=1,2,3)
-
数据压缩:
java复制.addInterceptor(new GzipRequestInterceptor()) -
DNS优化:
- 实现自定义Dns接口
- 使用HTTPDNS服务
1.4 安全防护方案
-
HTTPS证书校验:
java复制CertificatePinner certificatePinner = new CertificatePinner.Builder() .add("example.com", "sha256/AAAAAAAAAAAAAAAA=") .build(); -
敏感数据保护:
- 使用AndroidKeyStore存储密钥
- 请求参数加密处理
-
防抓包措施:
- 证书绑定(Certificate Pinning)
- 禁止代理检测
java复制if (BuildConfig.DEBUG) { client.proxy(Proxy.NO_PROXY); }
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 面试高频问题解析
2.1 OkHttp拦截器原理
拦截器采用责任链模式处理请求,典型流程:
- 应用拦截器(重试/重定向前调用)
- 网络拦截器(实际网络请求前调用)
- 缓存拦截器(检查可用缓存)
- 连接拦截器(建立TCP连接)
自定义拦截器示例:
java复制class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
logger.info(String.format("Sending request %s", request.url()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info(String.format("Received response in %.1fms", (t2-t1)/1e6d));
return response;
}
}
2.2 Retrofit动态代理机制
Retrofit通过Java动态代理将接口方法转换为HTTP请求:
- 创建Proxy实例
- 解析方法注解(GET/POST等)
- 构造RequestBuilder
- 调用OkHttp执行请求
2.3 HTTP状态码处理
重点掌握:
- 200 OK:成功响应
- 301/302:重定向处理
- 401:未授权(需刷新token)
- 403:禁止访问
- 404:资源不存在
- 500:服务器错误
推荐统一错误处理方式:
java复制public class ErrorHandlerInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (!response.isSuccessful()) {
throw new HttpException(response.code(), response.message());
}
return response;
}
}
3. 实战问题排查指南
3.1 常见异常场景
| 异常类型 | 可能原因 | 解决方案 |
|---|---|---|
| SSLHandshakeException | 证书验证失败 | 检查证书有效期/配置信任策略 |
| SocketTimeoutException | 连接超时 | 调整connectTimeout参数 |
| UnknownHostException | DNS解析失败 | 使用备用DNS或本地缓存 |
| ProtocolException | 协议不匹配 | 检查服务端HTTP版本兼容性 |
3.2 网络调试技巧
-
使用Stetho调试工具:
java复制dependencies { implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1' } -
抓包分析:
java复制.addNetworkInterceptor(new HttpLoggingInterceptor()) -
模拟弱网环境:
- Android Studio的Network Profiler
- 第三方工具如Charles限速
4. 最新技术趋势
4.1 Kotlin协程支持
Retrofit 2.6+原生支持协程:
kotlin复制interface ApiService {
@GET("users")
suspend fun getUsers(): List<User>
}
4.2 多路复用优化
HTTP/2特性:
- 单TCP连接并行处理多个请求
- 头部压缩减少开销
- 服务端推送支持
4.3 WebSocket长连接
OkHttp实现方案:
java复制Request request = new Request.Builder()
.url("ws://echo.websocket.org")
.build();
WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {
@Override
public void onMessage(WebSocket webSocket, String text) {
// 处理消息
}
});
5. 架构设计建议
5.1 分层设计原则
推荐架构:
code复制UI层 -> ViewModel -> Repository -> 网络层
↗
本地数据库
5.2 统一错误处理
建议方案:
- 定义业务错误码体系
- 全局异常拦截器
- 错误页面统一管理
5.3 自动重试机制
指数退避算法实现:
java复制private fun <T> Call<T>.executeWithRetry(maxRetries: Int = 3): T {
var currentRetry = 0
var lastException: IOException? = null
while (currentRetry < maxRetries) {
try {
return execute().body()!!
} catch (e: IOException) {
lastException = e
Thread.sleep(1000L shl currentRetry) // 2^retryNumber秒
currentRetry++
}
}
throw lastException!!
}
网络请求作为Android开发的核心能力,需要开发者深入理解底层原理并掌握最佳实践。建议在项目中实际应用这些方案,遇到具体问题时可以留言交流实战经验。
