0

First of all, I have 2 fragments and they show different json values(2 links). If I change fragment(.replace()), that fragment get values with retrofit and show it. It works well but other fragment is deleted with values. After change fragment, it downloads again so I change structure. I want to take 2 json objects once so I get json objects in mainactivity and fragments get these with methods. They work well in first opening but if i open a fragment second time, it gives this error. How can I solve it?

java.lang.IllegalStateException: Already executed.
at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:84)

Code is very long, i will show main structure.

MainActivity.java

public class MainActivity extends AppCompatActivity
{
    private Call<Restaurant[]> restaurantCall;
    private Call<Dining[]> diningCall;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Restaurant Json value
        RestaurantInterface restaurantInterface = RetroClient.getClient().create(RestaurantInterface.class);
        restaurantCall = restaurantInterface.getJsonValues();

        //Dininghall Json value
        DiningInterface diningInterface = RetroClient.getClient().create(DiningInterface.class);
        diningCall = diningInterface.getJsonValues();
    }
    public Call<Restaurant[]> RestaurantJson()
    {
        return this.restaurantCall;
    }

    public Call<Dining[]> DiningJson()
    {
        return this.diningCall;
    }
}

RestaurantFragment.java (Other fragment has same structure)

public class RestFragment extends Fragment
{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_rest, container, false);

        Call<Restaurant[]> call = ((MainActivity) getActivity()).RestaurantJson();

        call.enqueue(new Callback<Restaurant[]>()
        {
            .
            .
Roberto Martucci
  • 1,237
  • 1
  • 13
  • 21
ozo
  • 101
  • 1
  • 2
  • 13
  • Have a look at this https://stackoverflow.com/a/35094488/3172725. You cannot use the same call twice, you need to clone your call. – Roberto Martucci Dec 29 '17 at 23:22
  • I checked it but how can I use clone() for this? – ozo Dec 29 '17 at 23:36
  • `Call retryCall = call.clone();` `retryCall.enqueue(new Callback()`... or `public Call RestaurantJson() { return this.restaurantCall.clone(); }` – Roberto Martucci Dec 29 '17 at 23:39
  • Thank you, it worked. I did return this.restaurantCall.clone(); and return this.diningCall.clone(); However, I thought it will download json objects in main activity but it download them in fragments. Why and what is the solution? – ozo Dec 30 '17 at 09:02
  • I replied with an answer to this new question for convenience...it was too long for a comment – Roberto Martucci Dec 30 '17 at 12:47

1 Answers1

2

Summing up, in order to avoid the "Already executed" exception, clone the call:

public Call<Restaurant[]> RestaurantJson()
{
    return this.restaurantCall.clone();
}

public Call<Dining[]> DiningJson()
{
    return this.diningCall.clone();
}

If you want to execute the call in the activity and not in the fragment as you are actually doing, then you need to call enqueue(new Callbak(... in your activity. So you need something like this:

public class RestFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_rest, container, false);

        ((MainActivity) getActivity()).RestaurantJson(this);
    }

     public void onResponse(Response<T> response) {
         //your fragment code on response
     } 
    ...
}

public class MainActivity extends AppCompatActivity {

    public void RestaurantJson(final RestFragment fragment)
    {
        RestaurantInterface restaurantInterface = RetroClient.getClient().create(RestaurantInterface.class);
        restaurantCall = restaurantInterface.getJsonValues();
        restaurantCall.enqueue(new Callback<Restaurant[]>() {

        @Override
        public void onResponse(Call<T> call, Response<T> response) {
            ...
            fragment.onResponse(response);
        }
    }
    ...
}

The same for your DiningFragment and your dining call...

Roberto Martucci
  • 1,237
  • 1
  • 13
  • 21