Last active
September 18, 2018 17:55
-
-
Save stephenhand/0fdb6425353465875bbe3cd7343c3695 to your computer and use it in GitHub Desktop.
A class that permits the use of synchronous blocking HTTP requests in volley. It also makes no use of the main thread whilst handling requests (which volley does by default, even RequestFuture runs the code to make the response object available on the main thread). Instead it configures its own looper thread to process responses on.
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
package ie.com.handysolutions.android.http; | |
import android.content.Context; | |
import android.os.Handler; | |
import android.os.Looper; | |
import com.android.volley.ExecutorDelivery; | |
import com.android.volley.Network; | |
import com.android.volley.Request; | |
import com.android.volley.RequestQueue; | |
import com.android.volley.toolbox.BasicNetwork; | |
import com.android.volley.toolbox.DiskBasedCache; | |
import com.android.volley.toolbox.HurlStack; | |
import com.android.volley.toolbox.RequestFuture; | |
import java.io.File; | |
import java.util.concurrent.ExecutionException; | |
/** | |
* Created by stephenh on 25/10/2017. | |
* This class permits the use of synchronous blocking HTTP requests in volley. It also makes no use of the main thread, configuring its own looper thread to process responses on | |
*/ | |
public class SynchronousVolley { | |
private Handler responseHandler; | |
private final Thread responseThread = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
synchronized (SynchronousVolley.this) { | |
Looper.prepare(); | |
responseHandler = new Handler(Looper.myLooper()); | |
SynchronousVolley.this.notify(); | |
} | |
Looper.loop(); | |
} | |
}); | |
private static final String DEFAULT_CACHE_DIR = "volley"; | |
private final RequestQueue queue; | |
/** Number of network request dispatcher threads to start. */ | |
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4; | |
//Simplified version of Volley.newRequestQueue that permits specifying a custom handler for responses | |
//This allows you to run response handler code on threads other than the UI thread | |
private static RequestQueue newVolleyRequestQueue(Context context, Handler handler){ | |
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); | |
Network network = new BasicNetwork(new HurlStack()); | |
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, DEFAULT_NETWORK_THREAD_POOL_SIZE, new ExecutorDelivery(handler)); | |
queue.start(); | |
return queue; | |
} | |
public SynchronousVolley(Context ctx) { | |
synchronized (this){ | |
try { | |
responseThread.start(); | |
//10 seconds should be more than long enough to set up the looper | |
SynchronousVolley.this.wait(10000); | |
} catch (InterruptedException e) { | |
throw new RuntimeException(e); | |
} | |
if (responseHandler == null) { | |
throw new IllegalStateException("Failed to set up looper to handle HTTP requests"); | |
} | |
} | |
this.queue = newVolleyRequestQueue(ctx, responseHandler); | |
} | |
public <T> T request(final Request<T> request){ | |
RequestFuture<T> future = RequestFuture.newFuture(); | |
future.setRequest(request); | |
queue.add(request); | |
try { | |
return (T)future.get(); | |
} catch (InterruptedException e) { | |
throw new RuntimeException(e); | |
} catch (ExecutionException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment