Android HttpServer实现弹窗交互后响应客户端并添加超时
解决方案:基于CountDownLatch+Handler实现等待用户操作/超时响应
核心思路
不用AsyncTask的复杂逻辑,也避免Thread.sleep()阻塞整个进程,核心是用CountDownLatch让请求处理线程进入可控等待状态,结合UI线程的Handler实现弹窗交互与超时触发:
- 请求线程初始化CountDownLatch(计数为1),调用
await()进入等待,仅阻塞当前请求线程,不影响其他进程 - 通过Handler在UI线程弹出AlertDialog,用户点击按钮时触发
countDown()唤醒请求线程 - 用
Handler.postDelayed()设置10秒超时任务,到点自动触发countDown(),实现自动响应
具体实现步骤&代码示例
假设你的HttpServer在Activity中运行,代码如下:
public class MainActivity extends AppCompatActivity { private HttpServer httpServer; private Handler mainHandler; // 用原子类保证多线程下的结果安全,0=超时,1=用户确认,2=用户拒绝 private AtomicInteger responseResult = new AtomicInteger(0); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainHandler = new Handler(Looper.getMainLooper()); startHttpServer(); } private void startHttpServer() { try { httpServer = HttpServer.create(new InetSocketAddress(8080), 0); httpServer.createContext("/handle-request", new HttpHandler() { @Override public void handle(HttpExchange exchange) throws IOException { CountDownLatch latch = new CountDownLatch(1); responseResult.set(0); // 重置默认结果为超时 // 切换到UI线程弹出交互弹窗 mainHandler.post(() -> { AlertDialog dialog = new AlertDialog.Builder(MainActivity.this) .setTitle("收到外部请求") .setMessage("请求地址:" + exchange.getRequestURI()) .setPositiveButton("同意", (d, which) -> { responseResult.set(1); latch.countDown(); // 唤醒等待的请求线程 d.dismiss(); }) .setNegativeButton("拒绝", (d, which) -> { responseResult.set(2); latch.countDown(); d.dismiss(); }) .setCancelable(false) .create(); dialog.show(); }); // 10秒超时自动触发响应 mainHandler.postDelayed(() -> { responseResult.set(0); latch.countDown(); }, 10000); try { // 最多等待10秒,双重保障超时逻辑 latch.await(10, TimeUnit.SECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // 根据结果构建响应返回给客户端 String responseBody; int statusCode; switch (responseResult.get()) { case 1: responseBody = "用户已确认请求"; statusCode = HttpURLConnection.HTTP_OK; break; case 2: responseBody = "用户已拒绝请求"; statusCode = HttpURLConnection.HTTP_FORBIDDEN; break; default: responseBody = "请求超时,自动响应"; statusCode = HttpURLConnection.HTTP_GATEWAY_TIMEOUT; break; } exchange.sendResponseHeaders(statusCode, responseBody.getBytes(StandardCharsets.UTF_8).length); try (OutputStream os = exchange.getResponseBody()) { os.write(responseBody.getBytes(StandardCharsets.UTF_8)); } exchange.close(); } }); httpServer.start(); } catch (IOException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); // 销毁时清理资源,避免内存泄漏 if (httpServer != null) { httpServer.stop(0); } mainHandler.removeCallbacksAndMessages(null); } }
关键注意事项
- 线程安全:用
AtomicInteger存储响应结果,避免多线程读写冲突 - 生命周期管理:在
onDestroy中取消Handler的所有延迟任务、关闭HttpServer,防止内存泄漏 - 双重超时保障:既设置
Handler.postDelayed()触发countDown(),又在latch.await()中设置10秒超时,避免极端情况下的无限等待 - UI线程约束:HttpServer的请求处理线程是后台线程,必须通过Handler切换到UI线程操作AlertDialog
内容的提问来源于stack exchange,提问作者Ozgur Baykal
相关产品推荐
相关产品推荐

