0

While i was learning Dagger2 I made a naive service class that provides data assynchronously (in this case jokes from a funny api) but I encountered a problem and I kind of stuck with it. I'm using retrofit2 for requesting data from network.

But I can't figure out how to pull out the joke object retrieved from network (via response.body()), from anonymous internal class, into joke instance variable of the external class. I'm getting NullPointerException:

public class ChuckNorrisJokeService {
private Joke joke;

public String getJoke() {
    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("https://api.chucknorris.io")
            .build();

    JokeService jokeService = retrofit.create(JokeService.class);
    Call<Joke> call = jokeService.provideJoke();
    call.enqueue(new Callback<Joke>() {
        @Override
        public void onResponse(Call<Joke> call, Response<Joke> response) {
            joke = response.body();
        }

        @Override
        public void onFailure(Call<Joke> call, Throwable t) {
            System.out.println(t.getMessage());
        }
    });

    return joke.getContent();
}
}

The Joke class is a simple POJO:

public class Joke {
@SerializedName("value")
private String content;

public String getContent() {
    return content;
}
}

P.S. When calling synchronously the result is successful. How can I achieve the same functionality asynchronously?

P.S.S. I read this but it doesn't work for me and is so dirty.

The stacktrace is this:

Exception in thread "main" java.lang.NullPointerException
at com.alic.ChuckNorrisJokeService.getJoke(ChuckNorrisJokeService.java:41)
at com.alic.Application.run(Application.java:11)
at com.alic.Main.main(Main.java:6)

The Application and Main classes are very simple:

public class Application {
private ChuckNorrisJokeService chuckNorrisJokeService;

public Application() {
    this.chuckNorrisJokeService = new ChuckNorrisJokeService();
}

public void run() {
    System.out.println(chuckNorrisJokeService.getJoke());
}
}

and the Main class:

public class Main {
public static void main(String[] args) {
    Application app = new Application();
    app.run();
}

}

Andritchi Alexei
  • 1,380
  • 1
  • 16
  • 23
  • Please provide the full stacktrace for your exception. – Ben Mar 14 '18 at 13:56
  • 1
    `call.enqueue(new Callback() {...})` is a thread callback, when you run `joke.getContent()`, maybe not yet run `onResponse` to init data. – Heng Lin Mar 14 '18 at 15:37
  • Well, my question was how to solve this issue. I'm aware about callbacks and stuff. I asked because I hoped someone encountered the same issue like me and I hoped for a solution (a workaround maybe). – Andritchi Alexei Mar 14 '18 at 15:43
  • How do you do this synchronously? You should always get `NetworkOnMainThread` exception with Android 4.0 and above. – nhoxbypass Mar 14 '18 at 16:02
  • I just made a gradle project in intellij idea. There's no android code here. It's just plain old java with retrofit library for managing networking. I was fulling around with dependency injection and dagger2 container when I encountered this _java_ problem. – Andritchi Alexei Mar 14 '18 at 16:07
  • @AndritchiAlexei Sorry I thought you are asking in Android :( – nhoxbypass Mar 14 '18 at 16:10
  • I was specifically abstracting from android ecosystem just to concentrate on learning dagger2 library. – Andritchi Alexei Mar 14 '18 at 16:10

0 Answers0