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
相关产品推荐
相关产品推荐

