【问题标题】:Java function return a value before the function is executedJava函数在函数执行前返回一个值
【发布时间】:2019-04-29 09:17:16
【问题描述】:

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

我已经尝试使用 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());

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

我的错误是什么?

【问题讨论】:

  • 添加更多代码,例如您在何处以及如何调用代码来执行 Thread 类以及您在何处使用 API 响应。

标签: java android multithreading java-threads


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    好吧,如果您为 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();
    

    【讨论】:

    • 请注意ExecutorService.submit(...) 已经返回Future。无需在这里自己创建。
    • 它似乎不起作用,因为它阻塞了我的主线程。我正在寻找的东西更像是一个处理程序或来自 callAPI 的通知,它说“嘿,我完成了主线程,你现在可以调用静态结果了”
    • 您可以使用未来的异步消费者方法,例如 thenAccept 而不是 sync get
    猜你喜欢
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2010-09-15
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多