HttpURLConnection → OkHttp + Kotlin

HttpURLConnection → OkHttp + Kotlin

老写法(Java + HttpURLConnection)

java 复制代码
new Thread(() -> {
    HttpURLConnection connection = null;
    try {
        URL url = new URL("https://api.example.com/data");
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(10000);

        int code = connection.getResponseCode();
        if (code == 200) {
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            final String result = sb.toString();

            runOnUiThread(() -> updateUI(result));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (connection != null) connection.disconnect();
    }
}).start();

问题在哪里

手写 Socket 级别的连接管理、超时、流读取,代码量爆炸。线程切换全靠手动 new Thread + runOnUiThread。请求重试、缓存、HTTPS 证书校验全要自己实现,没有拦截器机制。

新写法(OkHttp + Coroutines)

添加依赖:

groovy 复制代码
implementation "com.squareup.okhttp3:okhttp:4.12.0"
kotlin 复制代码
private val client = OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .build()

viewModelScope.launch(Dispatchers.IO) {
    val request = Request.Builder()
            .url("https://api.example.com/data")
            .get()
            .build()

    try {
        val response = client.newCall(request).execute()
        if (response.isSuccessful) {
            val result = response.body?.string() ?: ""
            withContext(Dispatchers.Main) {
                updateUI(result)
            }
        }
    } catch (e: IOException) {
        withContext(Dispatchers.Main) {
            showError(e.message)
        }
    }
}

一句话注意

OkHttp 的 execute() 是同步方法,需要在后台线程调用。enqueue() 是异步回调,但用了协程就尽量用 execute() + 协程管理,避免回调嵌套。

response.body?.string() 只能调用一次,第二次返回空。如果需要反复读,先存到变量里。OkHttp 内部有自己的连接池和线程池,创建一次以单例使用即可,不要每次都 new。


Java Android 老项目迁移系列,持续更新中。

相关推荐
秋天的怀念_David4 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1004 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin4 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质5 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3765 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02146 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
步行cgn6 小时前
Spring MVC + Thymeleaf 模板解析失败:从 500 错误到页面正常显示
java·spring·mvc
lgcgkCQ7 小时前
【AI 转型实战 1】SpringAI 入门:搭建基础大模型对话能力
java·ai·agent·rag·spring ai·mcp·langchain4j
Wang's Blog7 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友
学到老活到老7 小时前
第 24 集:配置文件写了 80,Spring Boot 为什么读到 90?
java·后端·spring