Home Why can't I set a variable in onResponse?
Reply: 2

Why can't I set a variable in onResponse?

Paula Daniela
1#
Paula Daniela Published in 2018-01-12 12:44:02Z

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!

M.Waqas Pervez
2#
M.Waqas Pervez Reply to 2018-01-12 14:09:31Z

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.

Juan Cruz Soler
3#
Juan Cruz Soler Reply to 2018-01-12 12:52:01Z

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());
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.345784 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO