0

I am using Retrofit HTTP middle layer for API calls.Since Retrofit works async, I am using an interface to return API response back.But the declared interface is showing as NULL within the OnResponse() overriden method of Retrofit.

Below is the code block(s),

Interface

public interface OnResponseListener{
        void getCountryListResponse(ArrayList<String> list,int responseCode);
    }

OnResponse

            @Override
            public void onResponse(Call<List<Country>> call, Response<List<Country>> response) {

                Log.d("Response",response.body().toString());
                for (Country country: response.body())
                {
                    Log.d("Country",country.toString());
                    Log.d("CommomName",country.getCommonName());
                   // Log.d("BLLL",country.getCommonName());
                   countryList.add(country.getCommonName());
                }
                Log.d("Entered","Vikas Entered");
              //  Log.d("ResonseListener",mResponseListener.toString());//Here throwing error, mResponseListener is null object
                mResponseListener.getCountryListResponse(countryList,response.code());
            }

Interface Declaration

private  OnResponseListener mResponseListener;

I have no idea why it is NULL, even after the Object(Interface) is declared. Any help will be appreciated.

Abhay Koradiya
  • 2,068
  • 2
  • 15
  • 40

2 Answers2

1

I have bunch of suggestions for you.

  • Every object is null in Java, if you don't initialise it. See this answer.
  • Will you make 100 OnResponseListener interface for 100 types of response. That's why Java Generics come to scene.
  • Why not you make a common class which will make calls for you, and give expected response?

I am showing my class which will clear all these points

The code to call an webservice is just this.

If you have BaseModel type response.

Call<BaseModel> call;
new RetroService().call(call, new RetroService.OnResponseListenerRetro<BaseModel>() {
    @Override
    public void onSuccess(String tag, BaseModel response) {
        System.out.println(response);
    }

    @Override
    public void onError(String tag, RetroService.ErrorType error) {
        Toast.makeText(, "", Toast.LENGTH_SHORT).show();
    }
});

If you have Model2 type response.

Call<Model2> call;
new RetroService().call(call, new RetroService.OnResponseListenerRetro<Model2>() {
    @Override
    public void onSuccess(String tag, Model2 response) {
        System.out.println(response);
    }

    @Override
    public void onError(String tag, RetroService.ErrorType error) {
        Toast.makeText(, "", Toast.LENGTH_SHORT).show();
    }
});

Now you just need to create this class.

RetroService.java

import android.support.annotation.Nullable;
import android.util.Log;

import com.arsdigitech.angpau.R;
import com.arsdigitech.angpau.appClasses.App;
import com.google.gson.JsonSyntaxException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


public class RetroService {
    public static final String TAG = "RetroService***";

    public <T> void call(Call<T> call, OnResponseListenerRetro<T> onResponseListener) {
        call.enqueue(new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, Response<T> response) {
                if (response.isSuccessful()) {
                    onResponseListener.onSuccess("", response.body());
                } else {
                    ErrorType errorType = ErrorType.getErrorTypeByVolleyError(response.code());
                    onResponseListener.onError("", errorType);
                }
            }

            @Override
            public void onFailure(Call<T> call, Throwable t) {
                Log.e(TAG, t.getMessage());
                if (t instanceof JsonSyntaxException) {
                    onResponseListener.onError("", ErrorType.ParseError);
                } else {
                    onResponseListener.onError("", ErrorType.Error);
                }
            }
        });
    }


    public enum ErrorType {
        Error(R.string.error),
        RequestTimeoutError(R.string.timeoutError),
        NoConnectionError(R.string.noConnectionError),
        AuthFailureError(R.string.authFailureError),
        ServerError(R.string.serverError),
        NetworkError(R.string.networkError),
        BadRequestError(R.string.badRequestError),
        ForbiddenError(R.string.forbiddenError),
        NotFoundError(R.string.notFoundError),
        UnsupportedMediaType(R.string.unsupportedMediaType),
        MethodNotAllowedError(R.string.methodNotAllowedError),
        ParseError(R.string.parsing_error),;
        int message;

        ErrorType(int message) {
            this.message = message;
        }

        public String getMessage() {
            return App.getAppRes().getString(message);
        }

        public static @Nullable
        ErrorType getErrorTypeByVolleyError(int errorCode) {
            ErrorType errorType = null;
            switch (errorCode) {
                case 400:
                    errorType = ErrorType.BadRequestError;
                    break;
                case 401:
                    errorType = ErrorType.AuthFailureError;
                    break;
                case 403:
                    errorType = ErrorType.ForbiddenError;
                    break;
                case 404:
                    errorType = ErrorType.NotFoundError;
                    break;
                case 408:
                    errorType = ErrorType.RequestTimeoutError;
                    break;
                case 500:
                case 501:
                case 502:
                case 503:
                case 504:
                case 505:
                    errorType = ErrorType.ServerError;
                    break;
                default:
                    errorType = ErrorType.Error;
            }
            return errorType;
        }
    }

    public interface OnResponseListenerRetro<T> {
        void onSuccess(String tag, T response);
        void onError(String tag, ErrorType error);
    }

}
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
0

You will have to set value in it, and implement it from where you are calling it :

create a method :

public void setResponseListener(OnResponseListener mResponseListener){
    this.mResponseListener = mResponseListener;
}

and call it from where you are calling this call.enqueue() method like following registration :

    RestClientClassObject.setResponseListener(new OnResponseListener() {
        @Override
        void getCountryListResponse(ArrayList<String> list, int responseCode) {

            //write code you want to do with list

        }

    });
NehaK
  • 2,639
  • 1
  • 15
  • 31