0

I'm currently developping an android app which is accessing to an online API. I have a class dedicated to this task, and another class that just use the informations retrieved from the API. The problem is that when I call the API access class, it has to be asynchronous (defined by android studio) so I use a new Thread, but the return in the class that use the data is null, when the API access class return the good result.

I already tried to join the two threads with thread.join() but it doesn't work.

Here is the function that access the API in the API access class.The System.out at the end works as expected (I see the good result in the console)

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();

But when I try to do that in another class :

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

I get a null pointer exception because the return of the previous method is null.

What's my mistake here?

1
  • Add some more code like where and how you are calling your code to execute Thread class and where you are using the API Response. Commented Apr 29, 2019 at 9:28

2 Answers 2

3

This is probably because you have a data race. When you have to threads they execute in parallel, which in this case means your main thread reaches the System.out.println(retour.toString()); before your networking thread writes the response to the object.
You'll have to find a way to synchronize them to ensure this doesn't happen.
Seeing as you are on Android you might want to take a look at retrograde and OkHttp to abstract this low-level functionality away.

Sign up to request clarification or add additional context in comments.

Comments

2

Well, if you are using separate thread for the API call you can't expect it to be finished when you call retour.toString(). It's also a bad idea to store async operation result in static field as it wouldn't work in multi-threaded environment. You can try 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();

3 Comments

Notice that ExecutorService.submit(...) already returns a Future. No need to create one yourself here.
It doesn't seems to work because it blocks my main thread. The thing I'm searching for is more like a handler or a notify from the callAPI that say "hey main thread I finished, you can call the static result now"
You can use future async consumer methods like thenAccept instead of sync get

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.