地铁进隧道、电梯关门、Wi-Fi突然掉线——这些场景下,App 闪退、请求失败、页面白屏,用户第一反应不是骂网络,而是点叉关掉应用。其实,很多问题不靠“重开App”,靠一套靠谱的网络重连逻辑就能扛过去。
为什么移动端特别需要重连?
和 PC 不同,手机网络环境天然不稳定:蜂窝信号强弱频繁切换、Wi-Fi 和移动数据来回跳转、系统省电策略强制休眠后台连接。HTTP 请求一旦超时或被中断,客户端若不做干预,就只能干等用户手动刷新。
一个轻量但有效的重连策略
不追求“无限重试”,也不搞复杂状态机,核心就三条:检测是否断网、判断是否值得重试、控制重试节奏。
以 Android + OkHttp 为例,可在拦截器中加一层网络兜底:
public class RetryInterceptor implements Interceptor {
private static final int MAX_RETRY = 2;
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException exception = null;
for (int i = 0; i <= MAX_RETRY; i++) {
try {
response = chain.proceed(request);
if (response.isSuccessful()) {
return response;
}
} catch (IOException e) {
exception = e;
if (i == MAX_RETRY) throw e;
}
// 每次失败后延迟重试:1s → 2s → 4s
if (i < MAX_RETRY) {
try {
Thread.sleep((long) Math.pow(2, i) * 1000);
} catch (InterruptedException ignored) {}
}
}
throw exception;
}
}别只盯着 HTTP,DNS 和 TCP 层也得防
有时候请求没发出去,不是因为服务器没响应,而是 DNS 解析失败或 TCP 连接根本建不起来。iOS 上可以用 NWPathMonitor 监听网络路径变化:
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("网络已恢复,可触发缓存请求重发")
self.retryPendingRequests()
}
}
let queue = DispatchQueue(label: "NetworkMonitor")
monitor.start(queue: queue)用户感知比技术更重要
重连过程不能让用户傻等。建议:首次请求失败后,立即显示「正在重试…」小提示;第二次失败,改用「网络不太稳,稍等几秒再试」;第三次失败,才弹出明确提示并提供「手动重试」按钮。文字语气要像朋友提醒,而不是系统报错。
几个容易踩的坑
• POST 请求不能无脑重试(可能造成重复下单);
• 后台切到前台时,别一股脑重发所有待办请求,先检查当前网络类型(比如从 Wi-Fi 切到 4G,就该暂停大文件上传);
• 不要监听“网络可用”就立刻发请求——刚连上时 DNS 缓存可能还没更新,建议加 300ms 延迟再发。
真正健壮的重连,不是让代码多跑几次,而是让每一次重试都有理由、有节制、有反馈。