Last active
October 5, 2016 18:02
-
-
Save SarthakM9/8ba9d34afcbd6bbc38cb8f5480c19f3f to your computer and use it in GitHub Desktop.
A wrapper class around Volley Library, to make api calling a breeze. DO READ THE COMMENTS CAREFULLY!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The MIT License (MIT) | |
* | |
* Copyright (c) 2016 Sarthak Mittal | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in | |
* all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
* THE SOFTWARE. | |
*/ | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import com.android.volley.AuthFailureError; | |
import com.android.volley.DefaultRetryPolicy; | |
import com.android.volley.NetworkResponse; | |
import com.android.volley.ParseError; | |
import com.android.volley.Request; | |
import com.android.volley.Response; | |
import com.android.volley.VolleyError; | |
import com.android.volley.VolleyLog; | |
import com.android.volley.toolbox.HttpHeaderParser; | |
import com.google.gson.Gson; | |
import java.io.UnsupportedEncodingException; | |
import java.util.Map; | |
/** | |
* Custom Wrapper around Volley to send web requests along with headers if any. It provides the | |
* option to parse the data into model object using gson or return the raw response as a String. | |
* It also provides a single interface for response success and failure. You need to assign URLs | |
* a requestId to uniquely identify them and invoke/parse multiple web calls simultaneously. | |
*/ | |
public class CustomHttpRequest<T> extends Request<T> | |
{ | |
private String mRequestBody; | |
private Map<String, String> mRequestHeader; | |
private Class<T> mModelClass; | |
private final Gson mGson = new Gson(); | |
private static final String PROTOCOL_CHARSET = "utf-8"; | |
private static final String PROTOCOL_CONTENT_TYPE_JSON = String.format("application/json; " + | |
"charset=%s", PROTOCOL_CHARSET); | |
private static final String PROTOCOL_CONTENT_TYPE_URLENCODED = String.format | |
("application/x-www-form-urlencoded; charset=%s", PROTOCOL_CHARSET); | |
private InternalListener mInternalListener; | |
private int mRequestId; | |
private CustomHttpRequest() | |
{ | |
super(Method.GET, null, null); | |
} | |
/** | |
* @param method int specifying service type. ex: Request.Method.GET | |
* @param url URL to hit. | |
* @param requestID manually set id to keep track of the url being hit, it is used to keep | |
* track of response object and response error. | |
* @param header header to send, if any. | |
* @param body parameters to send(generally JSONObject) as a String, if any. | |
* @param timeOut timeOut in milliseconds. | |
* @param modelClass GSON model class object to populate data, pass null if raw String | |
* response is required. | |
* @param listener Custom response listener class object, return type of response is an | |
* Object which can further be cast to desired type using requestId. | |
*/ | |
public CustomHttpRequest(int method, @NonNull String url, int requestID, @Nullable | |
Map<String, String> header, @Nullable String body, int timeOut, @Nullable Class<T> | |
modelClass, HttpResponseListener listener) | |
{ | |
super(method, url, listener == null ? null : new InternalListener(listener, requestID)); | |
mInternalListener = (InternalListener) this.getErrorListener(); | |
mRequestId = requestID; | |
mRequestBody = body; | |
mRequestHeader = header; | |
mModelClass = modelClass; | |
setRetryPolicy(new DefaultRetryPolicy(timeOut, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, | |
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); | |
} | |
/** | |
* @param method int specifying service type. ex: Request.Method.GET | |
* @param url URL to hit. | |
* @param requestID manually set id to keep track of the url being hit, it is used to keep | |
* track of response object and response error. | |
* @param header header to send, if any. | |
* @param body parameters to send(generally JSONObject) as a String, if any. | |
* @param modelClass GSON model class object to populate data, pass null if raw String | |
* response is required | |
* @param listener Custom response listener class object, return type of response is an | |
* Object which can futher be cast to desired type using urlID. | |
*/ | |
public CustomHttpRequest(int method, @NonNull String url, int requestID, @Nullable | |
Map<String, String> header, @Nullable String body, @Nullable Class<T> modelClass, | |
HttpResponseListener listener) | |
{ | |
this(method, url, requestID, header, body, 12000, modelClass, listener); /*default time | |
is 12 secs*/ | |
} | |
/** | |
* Executes on a worker thread, parsing is done here. | |
*/ | |
@Override | |
protected Response<T> parseNetworkResponse(NetworkResponse response) | |
{ | |
try | |
{ | |
// The response is returned either as the type passed in modelClass argument or as a | |
// String if null is passed, note that the response is always up casted to an Object, | |
// You need to downcast it manually, on the basis of requestId parameter. | |
String responseString = new String(response.data, HttpHeaderParser.parseCharset | |
(response.headers, PROTOCOL_CHARSET)); | |
if (mModelClass == null) | |
{ | |
return Response.success((T) responseString, HttpHeaderParser.parseCacheHeaders | |
(response)); | |
} else | |
{ | |
return Response.success(mGson.fromJson(responseString, mModelClass), | |
HttpHeaderParser.parseCacheHeaders(response)); | |
} | |
} catch (UnsupportedEncodingException e) | |
{ | |
return Response.error(new ParseError(e)); | |
} catch (Exception e) | |
{ | |
return Response.error(new ParseError(e)); | |
} | |
} | |
/** | |
* Executes on the main thread; | |
*/ | |
@Override | |
protected void deliverResponse(T response) | |
{ | |
if (mInternalListener != null) | |
{ | |
mInternalListener.onResponse(response); | |
} | |
} | |
@Override | |
public Map<String, String> getHeaders() throws AuthFailureError | |
{ | |
return mRequestHeader != null ? mRequestHeader : super.getHeaders(); | |
} | |
@Override | |
public String getBodyContentType() | |
{ | |
// For setting another content type, apply switch statement on mRequestId | |
switch (mRequestId) | |
{ | |
// To change the content type for a particular endpoint, just add relevant case statement. | |
// case ID_AUTH_TOKEN: | |
// return PROTOCOL_CONTENT_TYPE_URLENCODED; | |
default: | |
return PROTOCOL_CONTENT_TYPE_JSON; | |
} | |
} | |
@Override | |
public byte[] getBody() | |
{ | |
try | |
{ | |
return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET); | |
} catch (UnsupportedEncodingException uee) | |
{ | |
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", | |
mRequestBody, PROTOCOL_CHARSET); | |
return null; | |
} | |
} | |
// Remove this method to get default volleyError object. | |
@Override | |
protected VolleyError parseNetworkError(VolleyError volleyError) | |
{ | |
if (volleyError.networkResponse != null && volleyError.networkResponse.data != null) | |
{ | |
volleyError = new VolleyError(new String(volleyError.networkResponse.data)); | |
} | |
return volleyError; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.os.Bundle; | |
import android.support.v7.app.AppCompatActivity; | |
import android.view.View; | |
import com.android.volley.Request; | |
import com.android.volley.VolleyError; | |
import com.android.volley.toolbox.Volley; | |
// Add import statements for your CustomHttpRequest and HttpResponseListener. | |
public class ExampleActivity extends AppCompatActivity implements HttpResponseListener | |
{ | |
private static final int ID_SERVICE_EXAMPLE = 1; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) | |
{ | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_example); | |
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() | |
{ | |
@Override | |
public void onClick(View v) | |
{ | |
invokeGetRequest(); | |
} | |
}); | |
} | |
private void invokeGetRequest() | |
{ | |
String url = "SOME_URL"; | |
CustomHttpRequest<YourGsonModelClass> request = new CustomHttpRequest<>(Request.Method | |
.GET, url, ID_SERVICE_EXAMPLE, null, null, YourGsonModelClass.class, this); | |
// Recommended to create a singleton of Volley RequestQueue in Application class. | |
Volley.newRequestQueue(this).add(request); | |
} | |
@Override | |
public void onResponseSuccess(Object response, int requestID) | |
{ | |
switch (requestID) | |
{ | |
case ID_SERVICE_EXAMPLE: | |
YourGsonModelClass model = (YourGsonModelClass) response; | |
// You get a completely parsed model. | |
break; | |
} | |
} | |
@Override | |
public void onResponseError(VolleyError error, int requestID) | |
{ | |
switch (requestID) | |
{ | |
case ID_SERVICE_EXAMPLE: | |
// Log error for this particular service. | |
break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The MIT License (MIT) | |
* | |
* Copyright (c) 2016 Sarthak Mittal | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in | |
* all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
* THE SOFTWARE. | |
*/ | |
import com.android.volley.Response; | |
import com.android.volley.VolleyError; | |
/** | |
* Interface which is implemented by other classes to get service response, it sends requestID as | |
* parameter along with the original volley response parameter. | |
* PUT THIS INSIDE THE SAME PACKAGE AS OF CustomHttpRequest.java | |
*/ | |
public interface HttpResponseListener | |
{ | |
void onResponseSuccess(Object response, int requestID); | |
void onResponseError(VolleyError error, int requestID); | |
} | |
/*This class is used internally in CustomHttpRequest class*/ | |
class InternalListener implements Response.ErrorListener, Response.Listener<Object> | |
{ | |
private final HttpResponseListener mListener; | |
private final int mRequestID; | |
public InternalListener(HttpResponseListener listener, int requestID) | |
{ | |
mListener = listener; | |
mRequestID = requestID; | |
} | |
@Override | |
public void onErrorResponse(VolleyError error) | |
{ | |
mListener.onResponseError(error, mRequestID); | |
} | |
@Override | |
public void onResponse(Object response) | |
{ | |
mListener.onResponseSuccess(response, mRequestID); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment