-3

recently I started using retrofit and I'm having a hard time trying to understand how it works.

I've came across with this, while trying to pass a variable, which is initialized in onResponse(), to another method to use it later.

The below code is the way I could think of to try to address the solution, but then i realized that the method loadList returned a null ItemList.

Question 1) I would like to know why is this happening, am i missing some knowledge about java or this approach is not the best solution?

Also, I noticed that if I want to use the value of list inside onResponse I am able to do so, with the value of response.body()

public ItemList loadList()

    Call<ItemList> call = retrofitInit().loadList();

    call.enqueue(new Callback<ItemList>() {
        @Override
        public void onResponse(Call<ItemList> call, Response<ItemList> response) {
            list = response.body();
            System.out.println(item.getItem().get(0).getName());
        }

        @Override
        public void onFailure(Call<ItemList> call, Throwable t) {
            System.out.println("FAILURE" + t.toString());
        }
    });

  return list; 

}

** UPDATE: **

private RestClient retrofitInit() {

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.0.49/Android/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    return retrofit.create(RestClient.class);
}

Question 2) Does anyone has any better solutions to do this? I've seen a lot of people using RxJava but I don't really want to get into it yet.

I appreciate all your comments, Thanks!

Paula Daniela
  • 115
  • 2
  • 10
  • Please post your `retrofitInit` function code. – Ircover Jan 12 '18 at 12:46
  • post your response and interface – AMAN SINGH Jan 12 '18 at 12:48
  • 1
    This is not how it works with methods which have asynchronous call. Use an interface to provide callback to calling entity . read [How to set callback](https://stackoverflow.com/questions/3398363/how-to-define-callbacks-in-android). – ADM Jan 12 '18 at 12:48
  • @Ircover I updated the post – Paula Daniela Jan 12 '18 at 12:49
  • [because enqueue is async call](https://ideone.com/PPHi95) 3. is loadList return statment in your case ... and 2. is onResponse call ... as you see the order is 1, 3, 2 – Selvin Jan 12 '18 at 12:51
  • @ADM I tried to use a callback, but it seems I had poor understanding of it, I'll try to do it again with the post you sent me, thanks! – Paula Daniela Jan 12 '18 at 12:54

2 Answers2

3

It is because onResponse is an asynchronous method that runs on a different thread.

The solution can be done with using an interface.

1 - Define an interface

public interface OnDataLoaded {

 onDataLoaded(ItemList itemlist);

}

2 - Pass the interface as the method argument

public ItemList loadList(OnDataLoaded onDataLoaded)

3 - Use the interface to pass the list.

public ItemList loadList(OnDataLoaded onDataLoaded){

Call<ItemList> call = retrofitInit().loadList();

call.enqueue(new Callback<ItemList>() {
    @Override
    public void onResponse(Call<ItemList> call, Response<ItemList> response) {

        list = response.body();
       onDataLoaded.onDataLoaded(list);
        System.out.println(item.getItem().get(0).getName());
    }

    @Override
    public void onFailure(Call<ItemList> call, Throwable t) {
        System.out.println("FAILURE" + t.toString());
    }
});

return list; 

}

4 - Use the interface in your Activity/Fragment.

public class yourActivity implements OnDataLoaded 

5 - You control will be transfered to you activity method onDataLoaded

@Override
public void onDataLoaded(ItemList itemList){
  // your item list will be available here.
  // you can use your bindings here.

   }

NOTE : wrote with without any IDE. might contain some syntax errors.

M.Waqas Pervez
  • 2,492
  • 2
  • 19
  • 33
1

onResponse is an asynchronous method.
Instead of returning the list you should call the method that uses the list inside onResponse:

@Override
public void onResponse(Call<ItemList> call, Response<ItemList> response) {
    methodThatUsesList(response.body());
}
Juan Cruz Soler
  • 8,172
  • 5
  • 41
  • 44