【发布时间】:2017-05-24 04:49:54
【问题描述】:
我目前正在将一个用 Objective-C 编写的网络库移植到 Java,我需要向服务器发出异步 HTTP 请求的功能,而不依赖任何第三方库(因此,没有 Apache 依赖项)。我正在使用HTTPUrlConnection 来执行此操作;但是,如您所知,这是一个同步过程。
我正在尝试使用ExecutorService 和Future<> 结构在此过程中实现并发。我需要使用Callable 而不是Runnable,因为我需要处理服务器发回给我的响应消息。以下是我正在做的事情的简要概述:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return postRequest(reqMsg);
}
});
其中 reqMsg 是请求消息(在 XML 中),而 postRequest 方法将响应消息作为字符串返回(也在 XML 中)。现在,为了检索这个 Callable 任务的返回值,我需要使用future.get()。但是,此方法是一个阻塞调用,这意味着它会阻塞主线程,直到响应可用。这不是我想要的。
我正在将一个 iOS 应用程序移植到 Android,并且我将使用 J2ObjC 在这些平台之间建立一个跨平台共享库。在 iOS 版本(即 Obj-C 版本的库)中,有完成处理程序来处理来自 HTTP 请求的结果,并且它是异步完成的。不幸的是,Java 在 Java 8 中使用 CompletableFuture 引入了这种回调方式来处理它。但是,Android 仅支持从 API 级别 24 开始的 CompletableFuture。我希望能够支持追溯到 Jelly Bean (API 16) 的 API 级别。据我所知,“对于与 Android 兼容的 JAR 文件,它只能引用作为 Android 的一部分可用的类以及在 JAR 本身中专门实现的其他类”。您可能会建议使用 AsyncTasks;但是,我想在 Java 网络端处理 HTTP 请求的并发性,因为这个库很可能会在两个平台之间共享。
我尝试过明确地使用线程;然而,当我研究它时,我发现为了使用 Callables,你需要使用 ExecutorService 和 Future (另外,似乎有一些与显式创建线程相关的性能开销 - 尽管我认为 TL:DR):
我不想依赖第三方库,除非绝对必要。
我不能使用
CompletableFuture,因为我希望我的最低 API 级别为 16。我不想在 Android 端使用
AsyncTasks处理这种并发,因为最初,这是在网络库中使用CompletionHandler(Objective-C) 处理的。
有没有办法在不阻塞的情况下使用Future.get()? (温馨提示,检查 Future.isDone() 的 while 循环也会阻塞主线程。
【问题讨论】:
-
请阅读How to Ask。你问题的文字很长,这个网站上的大多数人都会放弃阅读它。
标签: java android multithreading concurrency nonblocking