Java函数return函数执行前的值

Java function return a value before the function is executed

我目前正在开发一个 android 应用程序,它正在访问在线 API。我有一个 class 专用于此任务,另一个 class 只使用从 API 检索到的信息。问题是当我调用 API 访问 class 时,它必须是异步的(由 android studio 定义)所以我使用了一个新线程,但是 return class表示使用的数据为null,当API访问class时return效果不错。

我已经尝试使用 thread.join() 加入两个线程,但它不起作用。

这是访问 API 中的 API 访问 class.The System.out 最后按预期工作的函数(我在控制台中看到了良好的结果)

Thread t = new Thread() {
            public void run() {
                try {
                    String url = "-----------------------------------------------"+id;
                    URL obj = new URL(url);
                    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

                    con.setRequestMethod("GET");

                    con.setRequestProperty("x-api-key", "-------------------------------");
                    int responseCode = con.getResponseCode();

                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    HttpRequest.retour = new JSONArray(response.toString());
                    System.out.println(HttpRequest.retour.toString());
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        };
        t.start();

但是当我尝试在另一个 class 中这样做时:

System.out.println(retour.toString());

我得到一个空指针异常,因为前面方法的return是空的。

我这里有什么错误?

这可能是因为您有数据竞争。 当您必须线程时,它们并行执行,在这种情况下,这意味着您的主线程在您的网络线程将响应写入对象之前到达 System.out.println(retour.toString());
您必须找到一种方法来同步它们以确保不会发生这种情况。
既然你在 Android,你可能想看看 retrograde and OkHttp 来抽象掉这个低级功能。

好吧,如果您为 API 调用使用单独的线程,您不能指望它在您调用 retour.toString() 时完成。将异步操作结果存储在静态字段中也是一个坏主意,因为它在多线程环境中不起作用。你可以试试 Completable future:

public CompletableFuture<String> callApi() {
    CompletableFuture<String> completableFuture  = new CompletableFuture<>();
    Executors.newCachedThreadPool().submit(() -> {
        // your api call
        completableFuture.complete(apiResult);
        return null;
    });
    return completableFuture;
}

//in other thread call future synchronously
String result = completableFuture.get();