Last active
December 5, 2016 18:47
-
-
Save hendrawd/a6b0a89566ea4a525067b45a7dcea00b to your computer and use it in GitHub Desktop.
An OkHttp3Stack for Volley library to boost the performance of Volley itself
This file contains hidden or 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 com.android.volley.AuthFailureError; | |
import com.android.volley.Request; | |
import com.android.volley.toolbox.HttpStack; | |
import org.apache.http.HttpEntity; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.ProtocolVersion; | |
import org.apache.http.StatusLine; | |
import org.apache.http.entity.BasicHttpEntity; | |
import org.apache.http.message.BasicHeader; | |
import org.apache.http.message.BasicHttpResponse; | |
import org.apache.http.message.BasicStatusLine; | |
import java.io.IOException; | |
import java.util.Map; | |
import okhttp3.Call; | |
import okhttp3.Headers; | |
import okhttp3.MediaType; | |
import okhttp3.OkHttpClient; | |
import okhttp3.Protocol; | |
import okhttp3.RequestBody; | |
import okhttp3.Response; | |
import okhttp3.ResponseBody; | |
/** | |
* OkHttp backed {@link com.android.volley.toolbox.HttpStack HttpStack} that does not | |
* use okhttp-urlconnection | |
*/ | |
@SuppressWarnings("deprecation") | |
public class OkHttp3Stack implements HttpStack { | |
private static OkHttpClient sOkHttpClient; | |
public OkHttp3Stack() { | |
if (sOkHttpClient == null) { | |
sOkHttpClient = OkHttpSingleton.getInstance().getOkHttpClient(); | |
} | |
} | |
@Override | |
public HttpResponse performRequest(com.android.volley.Request<?> request, Map<String, String> additionalHeaders) | |
throws IOException, AuthFailureError { | |
okhttp3.Request.Builder okHttpRequestBuilder = new okhttp3.Request.Builder().url(request.getUrl()); | |
if (request.getTag() != null) { | |
okHttpRequestBuilder.tag(request.getTag()); | |
} | |
Map<String, String> headers = request.getHeaders(); | |
for (final String name : headers.keySet()) { | |
okHttpRequestBuilder.addHeader(name, headers.get(name)); | |
} | |
for (final String name : additionalHeaders.keySet()) { | |
okHttpRequestBuilder.addHeader(name, additionalHeaders.get(name)); | |
} | |
setConnectionParametersForRequest(okHttpRequestBuilder, request); | |
if (sOkHttpClient == null) { | |
sOkHttpClient = OkHttpSingleton.getInstance().getOkHttpClient(); | |
} | |
okhttp3.Request okHttpRequest = okHttpRequestBuilder.build(); | |
Call okHttpCall = sOkHttpClient.newCall(okHttpRequest); | |
Response okHttpResponse = okHttpCall.execute(); | |
StatusLine responseStatus = new BasicStatusLine(parseProtocol(okHttpResponse.protocol()), okHttpResponse.code(), okHttpResponse.message()); | |
BasicHttpResponse response = new BasicHttpResponse(responseStatus); | |
response.setEntity(entityFromOkHttpResponse(okHttpResponse)); | |
Headers responseHeaders = okHttpResponse.headers(); | |
for (int i = 0, len = responseHeaders.size(); i < len; i++) { | |
final String name = responseHeaders.name(i), value = responseHeaders.value(i); | |
if (name != null) { | |
response.addHeader(new BasicHeader(name, value)); | |
} | |
} | |
return response; | |
} | |
private static HttpEntity entityFromOkHttpResponse(Response r) throws IOException { | |
BasicHttpEntity entity = new BasicHttpEntity(); | |
ResponseBody body = r.body(); | |
entity.setContent(body.byteStream()); | |
entity.setContentLength(body.contentLength()); | |
entity.setContentEncoding(r.header("Content-Encoding")); | |
if (body.contentType() != null) { | |
entity.setContentType(body.contentType().type()); | |
} | |
return entity; | |
} | |
private static void setConnectionParametersForRequest(okhttp3.Request.Builder builder, com.android.volley.Request<?> request) | |
throws IOException, AuthFailureError { | |
switch (request.getMethod()) { | |
case Request.Method.DEPRECATED_GET_OR_POST: | |
// Ensure backwards compatibility. Volley assumes a request with a null body is a GET. | |
byte[] postBody = request.getPostBody(); | |
if (postBody != null) { | |
builder.post(RequestBody.create(MediaType.parse(request.getPostBodyContentType()), postBody)); | |
} | |
break; | |
case Request.Method.GET: | |
builder.get(); | |
break; | |
case Request.Method.DELETE: | |
builder.delete(); | |
break; | |
case Request.Method.POST: | |
builder.post(createRequestBody(request)); | |
break; | |
case Request.Method.PUT: | |
builder.put(createRequestBody(request)); | |
break; | |
case Request.Method.HEAD: | |
builder.head(); | |
break; | |
case Request.Method.OPTIONS: | |
builder.method("OPTIONS", null); | |
break; | |
case Request.Method.TRACE: | |
builder.method("TRACE", null); | |
break; | |
case Request.Method.PATCH: | |
builder.patch(createRequestBody(request)); | |
break; | |
default: | |
throw new IllegalStateException("Unknown method type."); | |
} | |
} | |
private static ProtocolVersion parseProtocol(final Protocol p) { | |
switch (p) { | |
case HTTP_1_0: | |
return new ProtocolVersion("HTTP", 1, 0); | |
case HTTP_1_1: | |
return new ProtocolVersion("HTTP", 1, 1); | |
case SPDY_3: | |
return new ProtocolVersion("SPDY", 3, 1); | |
case HTTP_2: | |
return new ProtocolVersion("HTTP", 2, 0); | |
} | |
throw new IllegalAccessError("Unkwown protocol"); | |
} | |
private static RequestBody createRequestBody(Request r) throws AuthFailureError { | |
final byte[] body = r.getBody(); | |
if (body == null) { | |
//avoid empty body that will throw IllegalArgumentException if the params is empty, | |
//so we will return RequestBody.create(MediaType.parse(r.getBodyContentType()), "") instead of null | |
return RequestBody.create(MediaType.parse(r.getBodyContentType()), ""); | |
} | |
return RequestBody.create(MediaType.parse(r.getBodyContentType()), body); | |
} | |
//cancel requests based on tag | |
public void cancelRequestOnGoing(Object tag) { | |
if (sOkHttpClient != null) { | |
for (Call call : sOkHttpClient.dispatcher().queuedCalls()) { | |
if (call.request().tag().equals(tag)) | |
call.cancel(); | |
} | |
for (Call call : sOkHttpClient.dispatcher().runningCalls()) { | |
if (call.request().tag().equals(tag)) | |
call.cancel(); | |
} | |
} | |
} | |
} |
This file contains hidden or 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.content.Context; | |
import com.android.volley.Request; | |
import com.android.volley.RequestQueue; | |
import com.android.volley.toolbox.Volley; | |
public class VolleySingleton { | |
private static VolleySingleton mInstance = null; | |
private RequestQueue mRequestQueue; | |
//private ImageLoader mImageLoader; | |
//private ImageLoader.ImageCache mImageCache; | |
private OkHttp3Stack mOkHttp3Stack; | |
private static final String TAG = VolleySingleton.class.getSimpleName(); | |
private VolleySingleton(Context context) { | |
//use okhttp stack | |
mOkHttp3Stack = new OkHttp3Stack(); | |
mRequestQueue = Volley.newRequestQueue(context, mOkHttp3Stack); | |
//default | |
//mRequestQueue = Volley.newRequestQueue(context); | |
//initiateImageLoader(); | |
} | |
// private void initiateImageLoader(){ | |
// mImageCache = new ImageLoader.ImageCache() { | |
// // int cacheSize = 1024 * 1024 * 10; | |
// private final BitmapLruCache mCache = new BitmapLruCache(); | |
// | |
// public void putBitmap(String url, Bitmap bitmap) { | |
// mCache.put(url, bitmap); | |
// } | |
// | |
// public Bitmap getBitmap(String url) { | |
// return mCache.get(url); | |
// } | |
// }; | |
// mImageLoader = new ImageLoader(this.mRequestQueue, mImageCache); | |
// } | |
public static synchronized VolleySingleton getInstance(Context context) { | |
if (mInstance == null) { | |
mInstance = new VolleySingleton(context); | |
} | |
return mInstance; | |
} | |
private RequestQueue getRequestQueue() { | |
return this.mRequestQueue; | |
} | |
// public ImageLoader getImageLoader() { | |
// return this.mImageLoader; | |
// } | |
// public ImageLoader.ImageCache getImageCache() { | |
// return this.mImageCache; | |
// } | |
/** | |
* Helper classes | |
*/ | |
public <T> void addToRequestQueue(Request<T> req, Object tag) { | |
// set the default tag if tag is empty | |
req.setTag(tag == null ? TAG : tag); | |
getRequestQueue().add(req); | |
} | |
public <T> void addToRequestQueue(Request<T> req) { | |
req.setTag(TAG); | |
getRequestQueue().add(req); | |
} | |
public void cancelPendingRequests(Object tag) { | |
if (mRequestQueue != null) { | |
mRequestQueue.cancelAll(tag); | |
mOkHttp3Stack.cancelRequestOnGoing(tag); | |
} | |
} | |
public void cancelPendingRequestsNoTag() { | |
if (mRequestQueue != null) { | |
mRequestQueue.cancelAll(TAG); | |
mOkHttp3Stack.cancelRequestOnGoing(TAG); | |
} | |
} | |
public void clearVolleyCache() { | |
if (mRequestQueue != null) { | |
mRequestQueue.getCache().clear(); | |
} | |
} | |
/** | |
* End helper classes | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment