Updated Volley

captchafix
Florens Douwes 11 years ago
parent 010a1c2cef
commit 197edd1d61
  1. 3
      Chan/src/com/android/volley/AuthFailureError.java
  2. 13
      Chan/src/com/android/volley/CacheDispatcher.java
  3. 4
      Chan/src/com/android/volley/ExecutorDelivery.java
  4. 25
      Chan/src/com/android/volley/NetworkDispatcher.java
  5. 2
      Chan/src/com/android/volley/NetworkError.java
  6. 4
      Chan/src/com/android/volley/NetworkResponse.java
  7. 2
      Chan/src/com/android/volley/ParseError.java
  8. 67
      Chan/src/com/android/volley/Request.java
  9. 33
      Chan/src/com/android/volley/RequestQueue.java
  10. 2
      Chan/src/com/android/volley/ServerError.java
  11. 6
      Chan/src/com/android/volley/VolleyLog.java
  12. 7
      Chan/src/com/android/volley/toolbox/AndroidAuthenticator.java
  13. 35
      Chan/src/com/android/volley/toolbox/BasicNetwork.java
  14. 6
      Chan/src/com/android/volley/toolbox/ClearCacheRequest.java
  15. 14
      Chan/src/com/android/volley/toolbox/DiskBasedCache.java
  16. 63
      Chan/src/com/android/volley/toolbox/HttpClientStack.java
  17. 6
      Chan/src/com/android/volley/toolbox/HttpHeaderParser.java
  18. 8
      Chan/src/com/android/volley/toolbox/HttpStack.java
  19. 41
      Chan/src/com/android/volley/toolbox/HurlStack.java
  20. 13
      Chan/src/com/android/volley/toolbox/ImageLoader.java
  21. 8
      Chan/src/com/android/volley/toolbox/ImageRequest.java
  22. 10
      Chan/src/com/android/volley/toolbox/JsonArrayRequest.java
  23. 10
      Chan/src/com/android/volley/toolbox/JsonObjectRequest.java
  24. 4
      Chan/src/com/android/volley/toolbox/JsonRequest.java
  25. 68
      Chan/src/com/android/volley/toolbox/NetworkImageView.java
  26. 8
      Chan/src/com/android/volley/toolbox/RequestFuture.java
  27. 4
      Chan/src/com/android/volley/toolbox/StringRequest.java
  28. 4
      Chan/src/com/android/volley/toolbox/Volley.java
  29. 2
      Chan/src/org/floens/chan/ChanApplication.java
  30. 6
      Chan/src/org/floens/chan/core/net/BitmapLruImageCache.java
  31. 1
      Chan/src/org/floens/chan/core/net/BoardsRequest.java
  32. 1
      Chan/src/org/floens/chan/core/net/ChanReaderRequest.java
  33. 26
      Chan/src/org/floens/chan/core/net/JsonReaderRequest.java
  34. 277
      Chan/src/org/floens/chan/ui/view/CustomNetworkImageView.java
  35. 29
      Chan/src/org/floens/chan/ui/view/NetworkPhotoView.java
  36. 4
      Chan/src/org/floens/chan/ui/view/PostView.java

@ -18,6 +18,9 @@ package com.android.volley;
import android.content.Intent;
import com.android.volley.NetworkResponse;
import com.android.volley.VolleyError;
/**
* Error indicating that there was an authentication failure when performing a Request.
*/

@ -16,10 +16,10 @@
package com.android.volley;
import java.util.concurrent.BlockingQueue;
import android.os.Process;
import java.util.concurrent.BlockingQueue;
/**
* Provides a thread for performing cache triage on a queue of requests.
*
@ -29,16 +29,15 @@ import android.os.Process;
* refresh are enqueued on the specified network queue for processing
* by a {@link NetworkDispatcher}.
*/
@SuppressWarnings("rawtypes")
public class CacheDispatcher extends Thread {
private static final boolean DEBUG = VolleyLog.DEBUG;
/** The queue of requests coming in for triage. */
private final BlockingQueue<Request> mCacheQueue;
private final BlockingQueue<Request<?>> mCacheQueue;
/** The queue of requests going out to the network. */
private final BlockingQueue<Request> mNetworkQueue;
private final BlockingQueue<Request<?>> mNetworkQueue;
/** The cache to read from. */
private final Cache mCache;
@ -59,7 +58,7 @@ public class CacheDispatcher extends Thread {
* @param delivery Delivery interface to use for posting responses
*/
public CacheDispatcher(
BlockingQueue<Request> cacheQueue, BlockingQueue<Request> networkQueue,
BlockingQueue<Request<?>> cacheQueue, BlockingQueue<Request<?>> networkQueue,
Cache cache, ResponseDelivery delivery) {
mCacheQueue = cacheQueue;
mNetworkQueue = networkQueue;
@ -88,7 +87,7 @@ public class CacheDispatcher extends Thread {
try {
// Get a request from the cache triage queue, blocking until
// at least one is available.
final Request request = mCacheQueue.take();
final Request<?> request = mCacheQueue.take();
request.addMarker("cache-queue-take");
// If the request has been canceled, don't bother dispatching it.

@ -16,10 +16,10 @@
package com.android.volley;
import java.util.concurrent.Executor;
import android.os.Handler;
import java.util.concurrent.Executor;
/**
* Delivers responses and errors.
*/

@ -16,12 +16,13 @@
package com.android.volley;
import java.util.concurrent.BlockingQueue;
import android.annotation.TargetApi;
import android.net.TrafficStats;
import android.os.Build;
import android.os.Process;
import java.util.concurrent.BlockingQueue;
/**
* Provides a thread for performing network dispatch from a queue of requests.
*
@ -30,10 +31,9 @@ import android.os.Process;
* eligible, using a specified {@link Cache} interface. Valid responses and
* errors are posted back to the caller via a {@link ResponseDelivery}.
*/
@SuppressWarnings("rawtypes")
public class NetworkDispatcher extends Thread {
/** The queue of requests to service. */
private final BlockingQueue<Request> mQueue;
private final BlockingQueue<Request<?>> mQueue;
/** The network interface for processing requests. */
private final Network mNetwork;
/** The cache to write to. */
@ -52,7 +52,7 @@ public class NetworkDispatcher extends Thread {
* @param cache Cache interface to use for writing responses to cache
* @param delivery Delivery interface to use for posting responses
*/
public NetworkDispatcher(BlockingQueue<Request> queue,
public NetworkDispatcher(BlockingQueue<Request<?>> queue,
Network network, Cache cache,
ResponseDelivery delivery) {
mQueue = queue;
@ -70,10 +70,18 @@ public class NetworkDispatcher extends Thread {
interrupt();
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void addTrafficStatsTag(Request<?> request) {
// Tag the request (if API >= 14)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
}
}
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Request request;
Request<?> request;
while (true) {
try {
// Take a request from the queue.
@ -96,10 +104,7 @@ public class NetworkDispatcher extends Thread {
continue;
}
// Tag the request (if API >= 14)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
}
addTrafficStatsTag(request);
// Perform the network request.
NetworkResponse networkResponse = mNetwork.performRequest(request);

@ -16,6 +16,8 @@
package com.android.volley;
import com.android.volley.NetworkResponse;
import com.android.volley.VolleyError;
/**
* Indicates that there was a network error when performing a Volley request.

@ -16,11 +16,11 @@
package com.android.volley;
import org.apache.http.HttpStatus;
import java.util.Collections;
import java.util.Map;
import org.apache.http.HttpStatus;
/**
* Data and headers returned from {@link Network#performRequest(Request)}.
*/

@ -16,6 +16,8 @@
package com.android.volley;
import com.android.volley.NetworkResponse;
import com.android.volley.VolleyError;
/**
* Indicates that the server's response could not be parsed.

@ -16,11 +16,6 @@
package com.android.volley;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.Handler;
@ -30,6 +25,11 @@ import android.text.TextUtils;
import com.android.volley.VolleyLog.MarkerLog;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;
/**
* Base class for all network requests.
*
@ -51,12 +51,19 @@ public abstract class Request<T> implements Comparable<Request<T>> {
int POST = 1;
int PUT = 2;
int DELETE = 3;
int HEAD = 4;
int OPTIONS = 5;
int TRACE = 6;
int PATCH = 7;
}
/** An event log tracing the lifetime of this request; for debugging. */
private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null;
/** Request method of this request. Currently supports GET, POST, PUT, and DELETE. */
/**
* Request method of this request. Currently supports GET, POST, PUT, DELETE, HEAD, OPTIONS,
* TRACE, and PATCH.
*/
private final int mMethod;
/** URL of this request. */
@ -127,7 +134,7 @@ public abstract class Request<T> implements Comparable<Request<T>> {
mErrorListener = listener;
setRetryPolicy(new DefaultRetryPolicy());
mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();
mDefaultTrafficStatsTag = findDefaultTrafficStatsTag(url);
}
/**
@ -140,9 +147,12 @@ public abstract class Request<T> implements Comparable<Request<T>> {
/**
* Set a tag on this request. Can be used to cancel all requests with this
* tag by {@link RequestQueue#cancelAll(Object)}.
*
* @return This Request object to allow for chaining.
*/
public void setTag(Object tag) {
public Request<?> setTag(Object tag) {
mTag = tag;
return this;
}
/**
@ -160,11 +170,30 @@ public abstract class Request<T> implements Comparable<Request<T>> {
return mDefaultTrafficStatsTag;
}
/**
* @return The hashcode of the URL's host component, or 0 if there is none.
*/
private static int findDefaultTrafficStatsTag(String url) {
if (!TextUtils.isEmpty(url)) {
Uri uri = Uri.parse(url);
if (uri != null) {
String host = uri.getHost();
if (host != null) {
return host.hashCode();
}
}
}
return 0;
}
/**
* Sets the retry policy for this request.
*
* @return This Request object to allow for chaining.
*/
public void setRetryPolicy(RetryPolicy retryPolicy) {
public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {
mRetryPolicy = retryPolicy;
return this;
}
/**
@ -216,16 +245,22 @@ public abstract class Request<T> implements Comparable<Request<T>> {
/**
* Associates this request with the given queue. The request queue will be notified when this
* request has finished.
*
* @return This Request object to allow for chaining.
*/
public void setRequestQueue(RequestQueue requestQueue) {
public Request<?> setRequestQueue(RequestQueue requestQueue) {
mRequestQueue = requestQueue;
return this;
}
/**
* Sets the sequence number of this request. Used by {@link RequestQueue}.
*
* @return This Request object to allow for chaining.
*/
public final void setSequence(int sequence) {
public final Request<?> setSequence(int sequence) {
mSequence = sequence;
return this;
}
/**
@ -255,9 +290,12 @@ public abstract class Request<T> implements Comparable<Request<T>> {
/**
* Annotates this request with an entry retrieved for it from cache.
* Used for cache coherency support.
*
* @return This Request object to allow for chaining.
*/
public void setCacheEntry(Cache.Entry entry) {
public Request<?> setCacheEntry(Cache.Entry entry) {
mCacheEntry = entry;
return this;
}
/**
@ -419,9 +457,12 @@ public abstract class Request<T> implements Comparable<Request<T>> {
/**
* Set whether or not responses to this request should be cached.
*
* @return This Request object to allow for chaining.
*/
public final void setShouldCache(boolean shouldCache) {
public final Request<?> setShouldCache(boolean shouldCache) {
mShouldCache = shouldCache;
return this;
}
/**

@ -16,6 +16,9 @@
package com.android.volley;
import android.os.Handler;
import android.os.Looper;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@ -25,9 +28,6 @@ import java.util.Set;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import android.os.Handler;
import android.os.Looper;
/**
* A request dispatch queue with a thread pool of dispatchers.
*
@ -35,7 +35,6 @@ import android.os.Looper;
* resolving from either cache or network on a worker thread, and then delivering
* a parsed response on the main thread.
*/
@SuppressWarnings("rawtypes")
public class RequestQueue {
/** Used for generating monotonically-increasing sequence numbers for requests. */
@ -51,28 +50,28 @@ public class RequestQueue {
* is <em>not</em> contained in that list. Is null if no requests are staged.</li>
* </ul>
*/
private final Map<String, Queue<Request>> mWaitingRequests =
new HashMap<String, Queue<Request>>();
private final Map<String, Queue<Request<?>>> mWaitingRequests =
new HashMap<String, Queue<Request<?>>>();
/**
* The set of all requests currently being processed by this RequestQueue. A Request
* will be in this set if it is waiting in any queue or currently being processed by
* any dispatcher.
*/
private final Set<Request> mCurrentRequests = new HashSet<Request>();
private final Set<Request<?>> mCurrentRequests = new HashSet<Request<?>>();
/** The cache triage queue. */
private final PriorityBlockingQueue<Request> mCacheQueue =
new PriorityBlockingQueue<Request>();
private final PriorityBlockingQueue<Request<?>> mCacheQueue =
new PriorityBlockingQueue<Request<?>>();
/** The queue of requests that are actually going out to the network. */
private final PriorityBlockingQueue<Request> mNetworkQueue =
new PriorityBlockingQueue<Request>();
private final PriorityBlockingQueue<Request<?>> mNetworkQueue =
new PriorityBlockingQueue<Request<?>>();
/** Number of network request dispatcher threads to start. */
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
/** Cache interface for retrieving and storing respones. */
/** Cache interface for retrieving and storing responses. */
private final Cache mCache;
/** Network interface for performing requests. */
@ -214,7 +213,7 @@ public class RequestQueue {
* @param request The request to service
* @return The passed-in request
*/
public Request add(Request request) {
public <T> Request<T> add(Request<T> request) {
// Tag the request as belonging to this queue and add it to the set of current requests.
request.setRequestQueue(this);
synchronized (mCurrentRequests) {
@ -236,9 +235,9 @@ public class RequestQueue {
String cacheKey = request.getCacheKey();
if (mWaitingRequests.containsKey(cacheKey)) {
// There is already a request in flight. Queue up.
Queue<Request> stagedRequests = mWaitingRequests.get(cacheKey);
Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey);
if (stagedRequests == null) {
stagedRequests = new LinkedList<Request>();
stagedRequests = new LinkedList<Request<?>>();
}
stagedRequests.add(request);
mWaitingRequests.put(cacheKey, stagedRequests);
@ -262,7 +261,7 @@ public class RequestQueue {
* <p>Releases waiting requests for <code>request.getCacheKey()</code> if
* <code>request.shouldCache()</code>.</p>
*/
void finish(Request request) {
void finish(Request<?> request) {
// Remove from the set of requests currently being processed.
synchronized (mCurrentRequests) {
mCurrentRequests.remove(request);
@ -271,7 +270,7 @@ public class RequestQueue {
if (request.shouldCache()) {
synchronized (mWaitingRequests) {
String cacheKey = request.getCacheKey();
Queue<Request> waitingRequests = mWaitingRequests.remove(cacheKey);
Queue<Request<?>> waitingRequests = mWaitingRequests.remove(cacheKey);
if (waitingRequests != null) {
if (VolleyLog.DEBUG) {
VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.",

@ -16,6 +16,8 @@
package com.android.volley;
import com.android.volley.NetworkResponse;
import com.android.volley.VolleyError;
/**
* Indicates that the error responded with an error response.

@ -16,13 +16,13 @@
package com.android.volley;
import android.os.SystemClock;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.os.SystemClock;
import android.util.Log;
/** Logging helper class. */
public class VolleyLog {
public static String TAG = "Volley";

@ -16,6 +16,8 @@
package com.android.volley.toolbox;
import com.android.volley.AuthFailureError;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
@ -23,8 +25,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.android.volley.AuthFailureError;
/**
* An Authenticator that uses {@link AccountManager} to get auth
* tokens of a specified type for a specified account.
@ -67,10 +67,11 @@ public class AndroidAuthenticator implements Authenticator {
return mAccount;
}
// TODO: Figure out what to do about notifyAuthFailure
@SuppressWarnings("deprecation")
@Override
public String getAuthToken() throws AuthFailureError {
final AccountManager accountManager = AccountManager.get(mContext);
@SuppressWarnings("deprecation")
AccountManagerFuture<Bundle> future = accountManager.getAuthToken(mAccount,
mAuthTokenType, mNotifyAuthFailure, null, null);
Bundle result;

@ -16,22 +16,6 @@
package com.android.volley.toolbox;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.cookie.DateUtils;
import android.os.SystemClock;
import com.android.volley.AuthFailureError;
@ -47,6 +31,22 @@ import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.cookie.DateUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* A network performing Volley requests over an {@link HttpStack}.
*/
@ -98,7 +98,8 @@ public class BasicNetwork implements Network {
// Handle cache validation.
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
request.getCacheEntry().data, responseHeaders, true);
request.getCacheEntry() == null ? null : request.getCacheEntry().data,
responseHeaders, true);
}
// Some responses such as 204s do not have content. We must check.

@ -16,14 +16,14 @@
package com.android.volley.toolbox;
import android.os.Handler;
import android.os.Looper;
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import android.os.Handler;
import android.os.Looper;
/**
* A synthetic request used for clearing the cache.
*/

@ -55,7 +55,7 @@ public class DiskBasedCache implements Cache {
private final int mMaxCacheSizeInBytes;
/** Default maximum disk usage in bytes. */
private static final int DEFAULT_DISK_USAGE_BYTES = 25 * 1024 * 1024;
private static final int DEFAULT_DISK_USAGE_BYTES = 50 * 1024 * 1024;
/** High water mark percentage for the cache */
private static final float HYSTERESIS_FACTOR = 0.9f;
@ -361,12 +361,12 @@ public class DiskBasedCache implements Cache {
*/
public CacheHeader(String key, Entry entry) {
this.key = key;
this.size = entry.data.length;
this.etag = entry.etag;
this.serverDate = entry.serverDate;
this.ttl = entry.ttl;
this.softTtl = entry.softTtl;
this.responseHeaders = entry.responseHeaders;
size = entry.data.length;
etag = entry.etag;
serverDate = entry.serverDate;
ttl = entry.ttl;
softTtl = entry.softTtl;
responseHeaders = entry.responseHeaders;
}
/**

@ -16,10 +16,9 @@
package com.android.volley.toolbox;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@ -28,22 +27,26 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* An HttpStack that performs request over an {@link HttpClient}.
*/
@SuppressWarnings("deprecation")
public class HttpClientStack implements HttpStack {
protected final HttpClient mClient;
@ -87,6 +90,7 @@ public class HttpClientStack implements HttpStack {
/**
* Creates the appropriate subclass of HttpUriRequest for passed in request.
*/
@SuppressWarnings("deprecation")
/* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
Map<String, String> additionalHeaders) throws AuthFailureError {
switch (request.getMethod()) {
@ -122,6 +126,18 @@ public class HttpClientStack implements HttpStack {
setEntityIfNonEmptyBody(putRequest, request);
return putRequest;
}
case Method.HEAD:
return new HttpHead(request.getUrl());
case Method.OPTIONS:
return new HttpOptions(request.getUrl());
case Method.TRACE:
return new HttpTrace(request.getUrl());
case Method.PATCH: {
HttpPatch patchRequest = new HttpPatch(request.getUrl());
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(patchRequest, request);
return patchRequest;
}
default:
throw new IllegalStateException("Unknown request method.");
}
@ -144,4 +160,35 @@ public class HttpClientStack implements HttpStack {
protected void onPrepareRequest(HttpUriRequest request) throws IOException {
// Nothing.
}
/**
* The HttpPatch class does not exist in the Android framework, so this has been defined here.
*/
public static final class HttpPatch extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "PATCH";
public HttpPatch() {
super();
}
public HttpPatch(final URI uri) {
super();
setURI(uri);
}
/**
* @throws IllegalArgumentException if the uri is invalid.
*/
public HttpPatch(final String uri) {
super();
setURI(URI.create(uri));
}
@Override
public String getMethod() {
return METHOD_NAME;
}
}
}

@ -16,14 +16,14 @@
package com.android.volley.toolbox;
import java.util.Map;
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import org.apache.http.impl.cookie.DateParseException;
import org.apache.http.impl.cookie.DateUtils;
import org.apache.http.protocol.HTTP;
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import java.util.Map;
/**
* Utility methods for parsing HTTP headers.

@ -16,13 +16,13 @@
package com.android.volley.toolbox;
import java.io.IOException;
import java.util.Map;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import org.apache.http.HttpResponse;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import java.io.IOException;
import java.util.Map;
/**
* An HTTP stack abstraction.

@ -16,6 +16,20 @@
package com.android.volley.toolbox;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import org.apache.http.Header;
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.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -29,20 +43,6 @@ import java.util.Map.Entry;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import org.apache.http.Header;
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 com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;
/**
* An {@link HttpStack} based on {@link HttpURLConnection}.
*/
@ -213,6 +213,19 @@ public class HurlStack implements HttpStack {
connection.setRequestMethod("PUT");
addBodyIfExists(connection, request);
break;
case Method.HEAD:
connection.setRequestMethod("HEAD");
break;
case Method.OPTIONS:
connection.setRequestMethod("OPTIONS");
break;
case Method.TRACE:
connection.setRequestMethod("TRACE");
break;
case Method.PATCH:
addBodyIfExists(connection, request);
connection.setRequestMethod("PATCH");
break;
default:
throw new IllegalStateException("Unknown method type.");
}

@ -15,9 +15,6 @@
*/
package com.android.volley.toolbox;
import java.util.HashMap;
import java.util.LinkedList;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.os.Handler;
@ -29,6 +26,10 @@ import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageRequest;
import java.util.HashMap;
import java.util.LinkedList;
/**
* Helper that handles loading and caching images from remote URLs.
@ -274,10 +275,10 @@ public class ImageLoader {
// Remove this request from the list of in-flight requests.
BatchedImageRequest request = mInFlightRequests.remove(cacheKey);
// Set the error for this request
request.setError(error);
if (request != null) {
// Set the error for this request
request.setError(error);
// Send the batched response
batchResponse(cacheKey, request);
}

@ -16,10 +16,6 @@
package com.android.volley.toolbox;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
@ -27,6 +23,10 @@ import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
/**
* A canned request for getting an image at a given URL and calling
* back with a decoded Bitmap.

@ -16,17 +16,17 @@
package com.android.volley.toolbox;
import java.io.UnsupportedEncodingException;
import org.json.JSONArray;
import org.json.JSONException;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.UnsupportedEncodingException;
/**
* A request for retrieving a {@link JSONArray} response body at a given URL.
*/

@ -16,17 +16,17 @@
package com.android.volley.toolbox;
import java.io.UnsupportedEncodingException;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
/**
* A request for retrieving a {@link JSONObject} response body at a given URL, allowing for an
* optional {@link JSONObject} to be passed in as part of the request body.

@ -16,8 +16,6 @@
package com.android.volley.toolbox;
import java.io.UnsupportedEncodingException;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
@ -25,6 +23,8 @@ import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyLog;
import java.io.UnsupportedEncodingException;
/**
* A request for retrieving a T type response body at a given URL that also
* optionally sends along a JSON body in the request specified.

@ -48,14 +48,7 @@ public class NetworkImageView extends ImageView {
/** Current ImageContainer. (either in-flight or finished) */
private ImageContainer mImageContainer;
/**
* Max amount to scale the image inside the view
*/
protected float mMaxScale = 1;
private int mFadeTime = -1;
public NetworkImageView(Context context) {
this(context, null);
}
@ -67,23 +60,7 @@ public class NetworkImageView extends ImageView {
public NetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* How larger the inner bitmap is to the view size.
* @param amount
*/
public void setMaxScale(float amount) {
mMaxScale = amount;
}
/**
* Animate the image fading in.
* @param duration of the animation in milliseconds
*/
public void setFadeIn(int time) {
mFadeTime = time;
}
/**
* Sets URL of the image that should be loaded into this view. Note that calling this will
* immediately either set the cached image (if available) or the default image specified by
@ -123,15 +100,19 @@ public class NetworkImageView extends ImageView {
* Loads the image for the view if it isn't already loaded.
* @param isInLayoutPass True if this was invoked from a layout pass, false otherwise.
*/
private void loadImageIfNecessary(final boolean isInLayoutPass) {
void loadImageIfNecessary(final boolean isInLayoutPass) {
int width = getWidth();
int height = getHeight();
boolean isFullyWrapContent = getLayoutParams() != null
&& getLayoutParams().height == LayoutParams.WRAP_CONTENT
&& getLayoutParams().width == LayoutParams.WRAP_CONTENT;
boolean wrapWidth = false, wrapHeight = false;
if (getLayoutParams() != null) {
wrapWidth = getLayoutParams().width == LayoutParams.WRAP_CONTENT;
wrapHeight = getLayoutParams().height == LayoutParams.WRAP_CONTENT;
}
// if the view's bounds aren't known yet, and this is not a wrap-content/wrap-content
// view, hold off on loading the image.
boolean isFullyWrapContent = wrapWidth && wrapHeight;
if (width == 0 && height == 0 && !isFullyWrapContent) {
return;
}
@ -143,7 +124,7 @@ public class NetworkImageView extends ImageView {
mImageContainer.cancelRequest();
mImageContainer = null;
}
setImageBitmap(null);
setDefaultImageOrNull();
return;
}
@ -155,10 +136,14 @@ public class NetworkImageView extends ImageView {
} else {
// if there is a pre-existing request, cancel it if it's fetching a different URL.
mImageContainer.cancelRequest();
setImageBitmap(null);
setDefaultImageOrNull();
}
}
// Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
int maxWidth = wrapWidth ? 0 : width;
int maxHeight = wrapHeight ? 0 : height;
// The pre-existing content of this view didn't match the current URL. Load the new image
// from the network.
ImageContainer newContainer = mImageLoader.get(mUrl,
@ -168,8 +153,6 @@ public class NetworkImageView extends ImageView {
if (mErrorImageId != 0) {
setImageResource(mErrorImageId);
}
NetworkImageView.this.onErrorResponse(error);
}
@Override
@ -189,25 +172,26 @@ public class NetworkImageView extends ImageView {
}
if (response.getBitmap() != null) {
if (mFadeTime > 0 && !isImmediate) {
setAlpha(0f);
animate().alpha(1).setDuration(mFadeTime);
}
setImageBitmap(response.getBitmap());
} else if (mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
}
}
}, (int)(width * mMaxScale), (int)(height * mMaxScale));
}, maxWidth, maxHeight);
// update the ImageContainer to be the new bitmap container.
mImageContainer = newContainer;
}
public void onErrorResponse(VolleyError error) {
private void setDefaultImageOrNull() {
if(mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
}
else {
setImageBitmap(null);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);

@ -16,15 +16,15 @@
package com.android.volley.toolbox;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
/**
* A Future that represents a Volley request.
*

@ -16,14 +16,14 @@
package com.android.volley.toolbox;
import java.io.UnsupportedEncodingException;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import java.io.UnsupportedEncodingException;
/**
* A canned request for retrieving the response body at a given URL as a String.
*/

@ -16,8 +16,6 @@
package com.android.volley.toolbox;
import java.io.File;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
@ -27,6 +25,8 @@ import android.os.Build;
import com.android.volley.Network;
import com.android.volley.RequestQueue;
import java.io.File;
public class Volley {
/** Default on-disk cache directory. */

@ -6,6 +6,7 @@ import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.PinnedManager;
import org.floens.chan.core.manager.PinnedManager.PinListener;
import org.floens.chan.core.manager.ReplyManager;
import org.floens.chan.core.net.BitmapLruImageCache;
import org.floens.chan.database.DatabaseManager;
import org.floens.chan.service.WatchService;
import org.floens.chan.utils.IconCache;
@ -17,7 +18,6 @@ import android.preference.PreferenceManager;
import android.view.ViewConfiguration;
import com.android.volley.RequestQueue;
import com.android.volley.extra.BitmapLruImageCache;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

@ -1,4 +1,4 @@
package com.android.volley.extra;
package org.floens.chan.core.net;
import android.graphics.Bitmap;
import android.util.LruCache;
@ -9,12 +9,12 @@ public class BitmapLruImageCache extends LruCache<String, Bitmap> implements Ima
public BitmapLruImageCache(int maxSize) {
super(maxSize);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
@Override
public Bitmap getBitmap(String url) {
return get(url);

@ -9,7 +9,6 @@ import android.util.JsonReader;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.extra.JsonReaderRequest;
public class BoardsRequest extends JsonReaderRequest<ArrayList<Board>> {
public BoardsRequest(String url, Listener<ArrayList<Board>> listener, ErrorListener errorListener) {

@ -14,7 +14,6 @@ import android.util.JsonReader;
import com.android.volley.ParseError;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.extra.JsonReaderRequest;
public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
private Loadable loadable;

@ -1,4 +1,4 @@
package com.android.volley.extra;
package org.floens.chan.core.net;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -19,41 +19,41 @@ import com.android.volley.toolbox.HttpHeaderParser;
public abstract class JsonReaderRequest<T> extends Request<T> {
protected final Listener<T> listener;
private VolleyError error;
public JsonReaderRequest(String url, Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = listener;
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
public void setError(VolleyError error) {
this.error = error;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
ByteArrayInputStream baos = new ByteArrayInputStream(response.data);
JsonReader reader = new JsonReader(new InputStreamReader(baos, "UTF-8"));
// long start = System.currentTimeMillis();
T read = readJson(reader);
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
// Log.e("Chan", "Total time: " + (System.currentTimeMillis() - start));
if (read == null) {
return Response.error(new VolleyError());
} else if (error != null) {
@ -65,7 +65,7 @@ public abstract class JsonReaderRequest<T> extends Request<T> {
return Response.error(new ParseError(e));
}
}
public abstract T readJson(JsonReader reader);
}

@ -0,0 +1,277 @@
/**
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.floens.chan.ui.view;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageContainer;
import com.android.volley.toolbox.ImageLoader.ImageListener;
/**
* Custom version of NetworkImageView
*
* Handles fetching an image from a URL as well as the life-cycle of the
* associated request.
*/
public class CustomNetworkImageView extends ImageView {
/** The URL of the network image to load */
private String mUrl;
/**
* Resource ID of the image to be used as a placeholder until the network
* image is loaded.
*/
private int mDefaultImageId;
/**
* Resource ID of the image to be used if the network response fails.
*/
private int mErrorImageId;
/** Local copy of the ImageLoader. */
private ImageLoader mImageLoader;
/** Current ImageContainer. (either in-flight or finished) */
private ImageContainer mImageContainer;
/**
* Max amount to scale the image inside the view
*/
private float mMaxScale = 1;
private int mFadeTime;
public CustomNetworkImageView(Context context) {
this(context, null);
}
public CustomNetworkImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* How larger the inner bitmap is to the defined view size.
*
* @param amount
*/
public void setMaxScale(float amount) {
mMaxScale = amount;
}
public float getMaxScale() {
return mMaxScale;
}
/**
* Animate the image fading in.
*
* @param duration
* duration of the fade animation in milliseconds
*/
public void setFadeIn(int time) {
mFadeTime = time;
}
/**
* Sets URL of the image that should be loaded into this view. Note that
* calling this will immediately either set the cached image (if available)
* or the default image specified by
* {@link CustomNetworkImageView#setDefaultImageResId(int)} on the view.
*
* NOTE: If applicable,
* {@link CustomNetworkImageView#setDefaultImageResId(int)} and
* {@link CustomNetworkImageView#setErrorImageResId(int)} should be called
* prior to calling this function.
*
* @param url
* The URL that should be loaded into this ImageView.
* @param imageLoader
* ImageLoader that will be used to make the request.
*/
public void setImageUrl(String url, ImageLoader imageLoader) {
mUrl = url;
mImageLoader = imageLoader;
// The URL has potentially changed. See if we need to load it.
loadImageIfNecessary(false);
}
/**
* Sets the default image resource ID to be used for this view until the
* attempt to load it completes.
*/
public void setDefaultImageResId(int defaultImage) {
mDefaultImageId = defaultImage;
}
/**
* Sets the error image resource ID to be used for this view in the event
* that the image requested fails to load.
*/
public void setErrorImageResId(int errorImage) {
mErrorImageId = errorImage;
}
public void onErrorResponse(VolleyError error) {
}
/**
* Loads the image for the view if it isn't already loaded.
*
* @param isInLayoutPass
* True if this was invoked from a layout pass, false otherwise.
*/
void loadImageIfNecessary(final boolean isInLayoutPass) {
int width = getWidth();
int height = getHeight();
boolean wrapWidth = false, wrapHeight = false;
if (getLayoutParams() != null) {
wrapWidth = getLayoutParams().width == LayoutParams.WRAP_CONTENT;
wrapHeight = getLayoutParams().height == LayoutParams.WRAP_CONTENT;
}
// if the view's bounds aren't known yet, and this is not a
// wrap-content/wrap-content
// view, hold off on loading the image.
boolean isFullyWrapContent = wrapWidth && wrapHeight;
if (width == 0 && height == 0 && !isFullyWrapContent) {
return;
}
// if the URL to be loaded in this view is empty, cancel any old
// requests and clear the
// currently loaded image.
if (TextUtils.isEmpty(mUrl)) {
if (mImageContainer != null) {
mImageContainer.cancelRequest();
mImageContainer = null;
}
setDefaultImageOrNull();
return;
}
// if there was an old request in this view, check if it needs to be
// canceled.
if (mImageContainer != null && mImageContainer.getRequestUrl() != null) {
if (mImageContainer.getRequestUrl().equals(mUrl)) {
// if the request is from the same URL, return.
return;
} else {
// if there is a pre-existing request, cancel it if it's
// fetching a different URL.
mImageContainer.cancelRequest();
setDefaultImageOrNull();
}
}
// Calculate the max image width / height to use while ignoring
// WRAP_CONTENT dimens.
int maxWidth = wrapWidth ? 0 : width;
int maxHeight = wrapHeight ? 0 : height;
// The pre-existing content of this view didn't match the current URL.
// Load the new image
// from the network.
ImageContainer newContainer = mImageLoader.get(mUrl, new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (mErrorImageId != 0) {
setImageResource(mErrorImageId);
}
CustomNetworkImageView.this.onErrorResponse(error);
}
@Override
public void onResponse(final ImageContainer response, boolean isImmediate) {
// If this was an immediate response that was delivered inside
// of a layout
// pass do not set the image immediately as it will trigger a
// requestLayout
// inside of a layout. Instead, defer setting the image by
// posting back to
// the main thread.
if (isImmediate && isInLayoutPass) {
post(new Runnable() {
@Override
public void run() {
onResponse(response, false);
}
});
return;
}
if (response.getBitmap() != null) {
setImageBitmap(response.getBitmap());
if (mFadeTime > 0 && !isImmediate) {
setAlpha(0f);
animate().alpha(1f).setDuration(mFadeTime);
}
} else if (mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
}
}
}, (int)(maxWidth * mMaxScale), (int)(maxHeight * mMaxScale));
// update the ImageContainer to be the new bitmap container.
mImageContainer = newContainer;
}
private void setDefaultImageOrNull() {
if (mDefaultImageId != 0) {
setImageResource(mDefaultImageId);
} else {
setImageBitmap(null);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
loadImageIfNecessary(true);
}
@Override
protected void onDetachedFromWindow() {
if (mImageContainer != null) {
// If the view was bound to an image request, cancel it and clear
// out the image from the view.
mImageContainer.cancelRequest();
setImageBitmap(null);
// also clear out the container so we can reload the image if
// necessary.
mImageContainer = null;
}
super.onDetachedFromWindow();
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
invalidate();
}
}

@ -10,62 +10,61 @@ import android.graphics.drawable.Drawable;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.NetworkImageView;
/**
* Extends NetworkImageView.
* Attaches a PhotoViewAttacher when setBitmap is called.
* Sets the progressBar to false when a bitmap gets set.
*/
public class NetworkPhotoView extends NetworkImageView {
public class NetworkPhotoView extends CustomNetworkImageView {
private PhotoViewAttacher attacher;
private OnLongClickListener longClickListener;
private OnViewTapListener viewTapListener;
private ImageViewFragment fragment;
public NetworkPhotoView(Context context) {
super(context);
}
public void setImageViewFragment(ImageViewFragment fragment) {
this.fragment = fragment;
}
public void setOnLongClickListenerToAttacher(OnLongClickListener listener) {
longClickListener = listener;
}
public void setOnViewTapListenerToAttacher(OnViewTapListener listener) {
viewTapListener = listener;
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
attacher = new PhotoViewAttacher(this);
attacher.setMaximumScale(mMaxScale);
attacher.setMaximumScale(getMaxScale());
attacher.setOnLongClickListener(longClickListener);
attacher.setOnViewTapListener(viewTapListener);
fragment.showProgressBar(false);
}
@Override
public void onErrorResponse(VolleyError error) {
super.onErrorResponse(error);
// TODO: out of memory. We need a new image viewer for *large* images. Maybe copy the one from the gallery.
System.gc();
Toast.makeText(getContext(), R.string.image_preview_failed, Toast.LENGTH_LONG).show();
fragment.showProgressBar(false);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (attacher != null) {
attacher.cleanup();
}

@ -46,7 +46,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
private boolean isBuild = false;
private LinearLayout full;
private LinearLayout right;
private NetworkImageView imageView;
private CustomNetworkImageView imageView;
private TextView titleView;
private TextView commentView;
private TextView repliesCountView;
@ -234,7 +234,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
full.setOrientation(HORIZONTAL);
// Create thumbnail
imageView = new NetworkImageView(context);
imageView = new CustomNetworkImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setFadeIn(100);

Loading…
Cancel
Save