Java函数在执行函数之前返回一个值

问题描述 投票:0回答:2

我目前正在开发一个访问在线API的Android应用程序。我有一个专门用于此任务的类,另一个类只使用从API检索的信息。问题是当我调用API访问类时,它必须是异步的(由android studio定义)所以我使用了一个新的Thread,但是当API访问类返回时,使用该数据的类的返回值为null好结果。

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

这是在API访问类中访问API的函数。最后的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();

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

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

我得到一个空指针异常,因为前一个方法的返回值为null。

我的错在哪里?

java android multithreading java-threads
2个回答
3
投票

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


2
投票

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

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();
© www.soinside.com 2019 - 2024. All rights reserved.