You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何同时发起多个OkHttp3请求控制ESP32步进电机

问题解答

你的需求完全可行,但当前代码里的AsyncTask.execute()默认是在串行线程池中执行任务,所以这些请求会按顺序排队运行,无法实现同时发起的效果。下面给你几种针对性的解决方法:

方法一:修改AsyncTask的执行模式

把new request_data().execute(url)改成使用并行线程池执行,这样每个请求任务会被同时分配到不同线程中处理:

// 替换原request_to_url里的execute调用
new request_data().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "http://" + ip_address + "/" + command);

方法二:改用OkHttp异步请求(更推荐)

AsyncTask在Android 11已被标记为废弃,直接用OkHttp的异步回调实现并发请求更灵活,也符合现代Android开发规范:

首先更新你的Connectivity类,新增异步请求方法:

public class Connectivity {
    // 复用同一个OkHttpClient实例,避免重复创建开销
    private static final OkHttpClient client = new OkHttpClient();

    // 保留原同步请求方法(如果需要)
    public static String getUrl(String urlEsp32) throws IOException {
        Request request = new Request.Builder()
                .url(urlEsp32)
                .build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    // 新增异步请求方法
    public static void getUrlAsync(String urlEsp32, Callback callback) {
        Request request = new Request.Builder()
                .url(urlEsp32)
                .build();
        client.newCall(request).enqueue(callback);
    }
}

然后修改request_to_url方法,直接调用异步接口:

public void request_to_url(String command) {
    ConnectivityManager connMgr = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

    if (networkInfo != null && networkInfo.isConnected()) {
        String url = "http://" + ip_address + "/" + command;
        Connectivity.getUrlAsync(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                // 请求失败需切回主线程弹Toast
                runOnUiThread(() -> 
                    Toast.makeText(activity_2.this, "请求失败: " + e.getMessage(), Toast.LENGTH_LONG).show()
                );
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    // 成功后的逻辑,如需更新UI也要切回主线程
                    runOnUiThread(() -> {
                        // 这里可添加日志或UI更新操作
                    });
                } else {
                    runOnUiThread(() -> 
                        Toast.makeText(activity_2.this, "请求错误: " + response.code(), Toast.LENGTH_LONG).show()
                    );
                }
            }
        });
    } else {
        Toast.makeText(activity_2.this, "未连接网络", Toast.LENGTH_LONG).show();
    }
}

这样每个请求会立刻发起异步调用,无需依赖AsyncTask的线程池限制,并发效率更高。

额外优化建议

  • 合并请求:当前要发8个独立请求,建议在ESP32端新增一个聚合接口(比如/batch-control),通过参数传递所有指令(如/batch-control?cmds=STEP,DIR,STEP2,...),只需一次请求就能完成所有控制,既减少网络开销,也避免并发请求可能带来的时序问题。
  • UI线程安全:所有更新UI的操作(比如弹Toast)必须通过runOnUiThread或Handler切回主线程执行,避免崩溃。
  • OkHttpClient复用:不要每次请求都新建OkHttpClient,复用同一个实例能提升性能,它本身是线程安全的。

内容的提问来源于stack exchange,提问作者ChillinCruz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:43:25