Skip to main content
4 of 7
added 1342 characters in body
nPn
  • 165
  • 1
  • 1
  • 7

Generic callback object, but I need the type parameter inside methods

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);

    }
}
nPn
  • 165
  • 1
  • 1
  • 7