Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create multiple Retrofit callbacks in same fragment - android

I'm trying to implement in fragment multiple buttons and each of this buttons need to get some data from web api.

I've created retrofit callback for one button. Now I have some trouble with creating another button to get data from another api.

here is my interface:

public interface APIService {

        @GET("/api/partners.json")
        Call<List<Partner>> getPartners();

        @GET("/api/drivers.json")
        Call<List<Driver>> getDrivers();

        @GET("/api/warehouses.json")
        Call<List<Warehouse>> getWarehuses();
}

This is my api helper class:

public class APIHelper {

    public static final String BASE_URL = "https://part-of-url.herokuapp.com/";

    public static APIService apiService;

    public static APIService getApiService() {
        if (apiService == null) {
            Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create()).build();
            apiService = retrofit.create(APIService.class);
        }
        return apiService;
    }
}

this is my driver pojo model(all pojo models are almost the same)

public class Driver {

    @Expose
    private List<String> driver_name = new ArrayList<String>();

    public List<String> getDriver_name() { return driver_name; }

    public void setDriver_name(List<String> driver_name) { this.driver_name = driver_name; }
}

And this is my Fragment where I have get callback for partners and need to implement another button to get drivers and third button to get some storages.

public class DownloadMain extends Fragment implements Callback<Partner> {

    private static final String TAG = DownloadMain.class.getSimpleName();

    private Button dloadPartners, takeDrivers, takeWarehouses, takeUsers, takeLogs;
    private Call callPartners;

    public DownloadMain() {}

    public DownloadMain newInstance() { return new DownloadMain(); }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

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

        dloadPartners = (Button) view.findViewById(R.id.downloadPartners);
        takeDrivers = (Button) view.findViewById(R.id.btnDrivers);
        dloadPartners.setOnClickListener(btnListener);
        takeDrivers.setOnClickListener(btnDrivers);

        callPartners = APIHelper.getApiService().getPartners();

        return view;
    }

    Button.OnClickListener btnListener = (new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            callPartners.clone().enqueue(DownloadMain.this);
            checkIfDataIsInTable();
        }
    });
 @Override
    public void onResponse(Call call, Response response) {

        if(response.body() == null) {
            try {
                response.errorBody().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Toast.makeText(getActivity(), "No Partners!", Toast.LENGTH_SHORT).show();
        } else {
            ArrayList<String> partners = (ArrayList<String>) response.body();

            ActiveAndroid.beginTransaction();
            try {
                for (int i = 0; i < partners.size() ; i++) {
                    Partners partner = new  Partners();
                    partner.name = String.valueOf(partners);
                    partner.save();
                    Log.d("partner_ ", String.valueOf(response.body()));
                }
                ActiveAndroid.setTransactionSuccessful();
            } finally {
                ActiveAndroid.endTransaction();
            }

            Log.d(TAG, "Number of partners received: " + partners.size());
            Toast.makeText(getActivity(), "Partners downloaded!", Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    public void onFailure(Call call, Throwable t) {

    }
}

Now I have trouble to implement second button to get data from api.

I would be grateful if someone could help me to implement second button to get drivers from api?!

like image 804
RubyDigger19 Avatar asked Sep 07 '16 20:09

RubyDigger19


2 Answers

With retrofit2 you can do the onResponse and onFailure inline with the call.enqueue, which lets you have multiple call types in the same activity since they are encapsulated within the call.enqueue()

// the following can be in the same activity
Call<YourPOJO1> call1 = client.callName1(params);
call1.enqueue(new Callback<YourPOJO1>() {
        @Override
        public void onResponse(Call<YourPOJO1> call, Response<YourPOJO1> response) {
            Log.d(TAG, "Call1 Succeeded");
            int code = response.code();
            if (code == 200) {
       // your parsing of POJO1 here
            } else {
                Log.d(TAG, "Error Happened");
            }
        }

        @Override
        public void onFailure(Call<YourPOJO1> call, Throwable t) {
            Log.d(TAG, "Call1 Failed");
        }
    });


Call<YourPOJO2> call2 = client.callName2(params);
call2.enqueue(new Callback<YourPOJO2>() {
        @Override
        public void onResponse(Call<YourPOJO2> call, Response<YourPOJO2> response) {
            Log.d(TAG, "Call2 Succeeded");
            int code = response.code();
            if (code == 200) {
       // your parsing of POJO2 here
            } else {
                Log.d(TAG, "Error Happened");
            }
        }

        @Override
        public void onFailure(Call<YourPOJO2> call, Throwable t) {
            Log.d(TAG, "Call2 Failed");
        }
    });
like image 53
Doug Voss Avatar answered Nov 08 '22 22:11

Doug Voss


You might be able to do this using a Base model such as:

@GET("mypath") 
Call<MyBaseModel<List<MyModel>>> getData();

implement the Callback in the fragment as

Callback<MyBaseModel<List<?>>>

An example of an MyBaseModel would be:

public class MyBaseModel<Data> {
  private String page;
  private Data[] results;

  public String getPage() {
     return page;
  }

  public Data[] getResults() {
     return results;
  }
}

The onResponse should return the:

 Callback<MyBaseModel<?>>

then just check if the result is an instance of your model using 'instanceOf'

like image 22
Angel Solis Avatar answered Nov 08 '22 21:11

Angel Solis