How to create generic class for api calling using RxJava and Retrofit in Kotlin?
My JAVA implementation is as ::
At first Add Gradle Dependency : (update to latest version if available)
//for retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
//for interceptor implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
//For BuildType : (if you want for various environment)
buildTypes { debug { buildConfigField "String", "SERVER_URL", '"DEV_URL"' debuggable true } release { buildConfigField "String", "SERVER_URL", '"LIVE_URL"' minifyEnabled false } }
//If environment is set Define BASE_URL using set environment:
String BASE_URL = BuildConfig.SERVER_URL + "url";
=======================================================
Create a class called RestClient For Retrofit Builder :
public class RestClient {
private static RestClient instance;
private ApiConstant apiInterface;
private OkHttpClient.Builder okHttpClientBuilder;
public RestClient() {
instance = this;
okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.connectTimeout(60, TimeUnit.SECONDS);
okHttpClientBuilder.writeTimeout(60, TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(60, TimeUnit.SECONDS);
//for logs of api response in debug mode
if (BuildConfig.DEBUG) {
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClientBuilder.addInterceptor(interceptor);
}
}
public static RestClient getInstance() {
return instance;
}
public ApiConstant getApiInterface() {
final Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
retrofitBuilder.baseUrl(ApiConstant.BASE_URL);
retrofitBuilder.client(okHttpClientBuilder.build());
retrofitBuilder.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = retrofitBuilder.build();
apiInterface = retrofit.create(ApiConstant.class);
return apiInterface;
}
}
=======================================================
ApiInterface : (an interface for api calls)
public interface ApiInterface {
@POST("Urls Params")
Call<ModelClass> postValidateToken(@Body JSONObject body);
}
=======================================================
Create Generic class called RetrofitCallback which handles Api response and Throws basic errors and show Toast Message to user:
public abstract class RetrofitCallback<T> implements Callback<T> {
private ProgressDialog progressDialog;
private Context context;
private boolean validateResponse = true;
public RetrofitCallback(Context c) {
context = c;
}
public RetrofitCallback(Context c, ProgressDialog dialog) {
progressDialog = dialog;
context = c;
}
public RetrofitCallback(Context context, ProgressDialog progressDialog, boolean validateResponse) {
this.progressDialog = progressDialog;
this.context = context;
this.validateResponse = validateResponse;
}
public RetrofitCallback(Context context, boolean validateResponse) {
this.context = context;
this.validateResponse = validateResponse;
}
public abstract void onSuccess(T arg0);
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (!(((Activity) context).isFinishing()) && progressDialog != null && progressDialog.isShowing()) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
if (response.isSuccessful() && response.code() == 200) {
onSuccess(response.body());
} else {
Toast.makeText(context, context.getString(R.string.something_wrong), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<T> call, Throwable error) {
if (!validateResponse)
return;
String errorMsg;
error.printStackTrace();
if (error instanceof SocketTimeoutException) {
errorMsg = context.getString(R.string.connection_timeout);
} else if (error instanceof UnknownHostException) {
errorMsg = context.getString(R.string.nointernet);
} else if (error instanceof ConnectException) {
errorMsg = context.getString(R.string.server_not_responding);
} else if (error instanceof JSONException || error instanceof JsonSyntaxException) {
errorMsg = context.getString(R.string.parse_error);
} else if (error instanceof IOException) {
errorMsg = error.getMessage();
} else {
errorMsg = context.getString(R.string.something_wrong);
}
if (progressDialog != null && progressDialog.isShowing()) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show();
}
}
=======================================================
String : (string.xml)
Something went wrong. Please try again later. No internet connection available. Please try again later. Server is not responding. Please try again later. Connection Timeout Unable to parse response from server
=======================================================
Implementation (How to call in Activity or Fragment):
Call<User> userLoginCall = RestClient.getInstance().getApiInterface().LoginURL(Util.currentLanguage,
Util.getLoginURL(getActivity(), email, LOGIN_GOOGLE, accID));
userLoginCall.enqueue(new RetrofitCallback<User>(getActivity(), DialogUtils.showProgressDialog(getActivity())) {
@Override
public void onSuccess(User user) {
//Your Response
}
});
retrofitBuilder.addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
- Makotosan