Inside my android app, I currently have methods that look like below code.
Since they all need a callback object that basically does the same thing and I would like to try to eliminate the duplicated code seen below.
The object that gets posted via the mBus.post(response);
statement needs to be the specific type.
@Subscribe
public void onLeave(LeaveRequest event) {
mRailsApi.leave(event.getEmail(), event.getPassword(),
new Callback<LeaveResponse>() {
@Override
public void failure(RetrofitError arg0) {
LeaveResponse response = new LeaveResponse();
response.setSuccessful(false);
mBus.post(response);
}
@Override
public void success(LeaveResponse leaveResponse,
Response arg1) {
// need to create one since the api just returns a
// header with no body , hence the response is null
LeaveResponse response = new LeaveResponse();
response.setSuccessful(true);
mBus.post(response);
}
});
}
@Subscribe
public void onGetUsers(GetUsersRequest event) {
mRailsApi.getUsers(mApp.getToken(), new Callback<GetUsersResponse>() {
@Override
public void failure(RetrofitError arg0) {
GetUsersResponse response = (GetUsersResponse) arg0.getBody();
response.setSuccessful(false);
mBus.post(response);
}
@Override
public void success(GetUsersResponse getUsersResponse, Response arg1) {
getUsersResponse.setSuccessful(true);
mBus.post(getUsersResponse);
}
});
}
Here is what I have come up with so far. It seems to work but I am wondering if there is a better solution.
One thing that bothers me is, that I have both the type parameter for the class and I am passing in the class to the constructor. It seems like I should not need to pass in the same info in two different ways.
The method calls become this:
@Subscribe
public void onLeave(LeaveRequest event) {
System.out.println("inside api repo - making leave request");
LeaveResponse response = new LeaveResponse();
mRailsApi.leave(event.getEmail(), event.getPassword(),
new RailsApiCallback<LeaveResponse>(mBus, LeaveResponse.class ));
}
And this is the callback class :
public class RailsApiCallback<T extends BaseResponse> implements Callback<T> {
private Bus mBus;
private Class mType;
public RailsApiCallback(Bus bus, Class type) {
super();
mBus = bus;
mType = type;
}
@Override
public void failure(RetrofitError retrofitError) {
T response = (T) retrofitError.getBody();
response.setSuccessful(false);
mBus.post(mType.cast(response));
}
@Override
public void success(T convertedResponse, Response rawResponse) {
T response = null;
try {
response = (T) (convertedResponse != null ? convertedResponse : mType.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
response.setSuccessful(true);
mBus.post(mType.cast(response));
}
}
***** Update *****
Here is what I currently have:
@Subscribe
public void onLeave(LeaveRequest event) {
System.out.println("inside api repo - making leave request");
mRailsApi.leave(event.getEmail(), event.getPassword(),
new RailsApiCallback<LeaveResponse>(mBus, new LeaveResponse() ));
}
public class RailsApiCallback<T extends BaseResponse> implements Callback<T> {
private Bus mBus;
private T mResponse;
public RailsApiCallback(Bus bus, T response) {
super();
mBus = bus;
mResponse = response;
}
@Override
public void failure(RetrofitError retrofitError) {
System.out.println(retrofitError.toString());
T response = (T) retrofitError.getBody() != null ? (T) retrofitError.getBody() : mResponse ;
response.setRawResponse(retrofitError.getResponse());
response.setSuccessful(false);
mBus.post(response);
}
@Override
public void success(T convertedResponse, Response rawResponse) {
System.out.println(rawResponse.getBody());
T response = convertedResponse != null ? convertedResponse : mResponse ;
response.setSuccessful(true);
response.setRawResponse(rawResponse);
mBus.post(response);
}
}