├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ ├── android
│ │ └── volley
│ │ │ ├── AuthFailureError.java
│ │ │ ├── Cache.java
│ │ │ ├── CacheDispatcher.java
│ │ │ ├── DefaultRetryPolicy.java
│ │ │ ├── ExecutorDelivery.java
│ │ │ ├── Network.java
│ │ │ ├── NetworkDispatcher.java
│ │ │ ├── NetworkError.java
│ │ │ ├── NetworkResponse.java
│ │ │ ├── NoConnectionError.java
│ │ │ ├── ParseError.java
│ │ │ ├── Request.java
│ │ │ ├── RequestQueue.java
│ │ │ ├── Response.java
│ │ │ ├── ResponseDelivery.java
│ │ │ ├── RetryPolicy.java
│ │ │ ├── ServerError.java
│ │ │ ├── TimeoutError.java
│ │ │ ├── VolleyError.java
│ │ │ ├── VolleyLog.java
│ │ │ └── toolbox
│ │ │ ├── AndroidAuthenticator.java
│ │ │ ├── Authenticator.java
│ │ │ ├── BasicNetwork.java
│ │ │ ├── ByteArrayPool.java
│ │ │ ├── ClearCacheRequest.java
│ │ │ ├── DiskBasedCache.java
│ │ │ ├── HttpClientStack.java
│ │ │ ├── HttpHeaderParser.java
│ │ │ ├── HttpStack.java
│ │ │ ├── HurlStack.java
│ │ │ ├── ImageLoader.java
│ │ │ ├── ImageRequest.java
│ │ │ ├── JsonArrayRequest.java
│ │ │ ├── JsonObjectRequest.java
│ │ │ ├── JsonRequest.java
│ │ │ ├── NetworkImageView.java
│ │ │ ├── NoCache.java
│ │ │ ├── PoolingByteArrayOutputStream.java
│ │ │ ├── RequestFuture.java
│ │ │ ├── StringRequest.java
│ │ │ └── Volley.java
│ │ └── vinaysshenoy
│ │ └── okulusdemo
│ │ ├── DemoApplication.java
│ │ ├── MainActivity.java
│ │ ├── fragments
│ │ ├── ComparisonFragment.java
│ │ ├── NetworkFragment.java
│ │ └── RoundedRectanglesFragment.java
│ │ └── utils
│ │ └── RawBitmapManager.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-nodpi
│ ├── img_for_uri.jpg
│ └── img_res.jpg
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── activity_main.xml
│ ├── fragment_comparison.xml
│ ├── fragment_rounded_rectangles.xml
│ ├── layout_image_1.xml
│ ├── layout_image_2.xml
│ ├── layout_image_3.xml
│ ├── layout_image_4.xml
│ ├── layout_image_5.xml
│ └── layout_image_6.xml
│ ├── menu
│ └── main.xml
│ ├── raw
│ ├── img_1.jpg
│ ├── img_2.jpg
│ ├── img_3.jpg
│ ├── img_4.jpg
│ ├── img_5.jpg
│ └── img_6.jpg
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── maventask.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── vinaysshenoy
│ │ └── okulus
│ │ ├── OkulusDrawable.java
│ │ └── OkulusImageView.java
│ └── res
│ └── values
│ └── attrs.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 | .DS_Store
26 |
27 | #IntelliJ
28 | .idea/
29 | *.iml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | okulus(BETA)
2 | ============
3 | Custom Imageview for Android that allows for setting shapes/borders/shadows efficiently. This is currently in Beta as some minor issues are getting ironed out.
4 |
5 | Demo app is coming on the Play Store soon!
6 |
7 | The basic concept for drawing Bitmaps with a shape without creating a new Bitmap is based on [Romain Guy](https://plus.google.com/+RomainGuy)'s article on drawing [Bitmaps with Rounded Corners](http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/).
8 |
9 | ### Usage
10 | 1. Clone the repository and add the library to your project.
11 |
12 | 2. Add the custom namespace attribute to your layout
13 | ```xml
14 | xmlns:okulus="http://schemas.android.com/apk/res/com.vinaysshenoy.okulus
15 | ```
16 |
17 | 3. Add `OkulusImageView` to your layout and set the attributes you need
18 | ```xml
19 |
30 | ```
31 |
32 | 4. Call `setImageBitmap()` and you're done!
33 | ```java
34 | OkulusImageView imageView = findViewById(R.id.image_1);
35 | imageView.setImageBitmap(bitmap);
36 | ```
37 |
38 | ### Custom Attributes
39 | 1. `okulus_cornerRadius(dimension)` - Sets the corner radius used for adding the rounded corners. Set it to 50% of the width(for a square image) to make it a full circle. Default `0dp`.
40 | 2. `okulus_fullCircle(boolean)` - If this is set to `true`, the entire Bitmap will be drawn as a circle. The width and height will be set to whichever is smaller among them, and `cornerRadius` attribute will be ignored. Default `false`.
41 | 3. `okulus_borderWidth(dimension)` - Sets the width of the border to be drawn. Will be capped at `5dp`.
42 | 4. `okulus_borderColor(color)` - Sets the color of the border to draw. Default color is `#FF000000`.
43 | 5. `okulus_shadowWidth(dimension)` - Sets the width of the shadow to draw. Will be capped at `3dp`.
44 | 6. `okulus_shadowColor(color)` - Sets the color of the shadow to draw. Default is `#B3444444`.
45 | 7. `okulus_shadowRadius(float)` - Defines how sharp the shadow is. Set it to a small value(~0.5) for sharp shadows, and larger values for soft shadows. Default `0.5`
46 | 8. `okulus_touchSelectorColor(color)` - Defines the colour of the color overlayed on the view when it is touched. This is ignored if `touchSelectorEnabled` is `false`. Default `#66444444`
47 | 9. `okulus_touchSelectorEnabled(boolean)` - Defines whether the touch selectors should be drawn or not. Default is `false`
48 |
49 | ### Pros
50 | 1. No extra memory used for creating the reshaped Bitmap
51 | 2. Zero overdraw
52 | 3. Any combination of shapes - Rounded Rects, Rects, Squares, Circles are possible with borders + shadow
53 |
54 | ### Limitations
55 | 1. Supports only fixed dimensions. `wrap_content` cannot be used.
56 | 2. Does not respect the `scaleType` attribute of `ImageView`. Scaled Bitmaps need to be provided.
57 | 3. Shadows cannot be used without borders
58 | 4. Attributes can only be set through XML
59 | 5. Shadows are currently drawn to the right and bottom of the View and cannot be changed.
60 |
61 | ## Roadmap
62 | ### Version 1.0
63 | 1. Adding `get()` and `set()` attributes for `OkulusImageView` for setting attributes through code
64 | 2. Respecting ImageView's `scaleType` attribute
65 |
66 | ### Future(in descending order of priority)
67 | 1. Adding support for `wrap_content`
68 | 2. Adding support for any configuration of shadows
69 | 3. Adding support for color filters to easily configure effects like Sepia, Grayscale etc.
70 | 4. Adding support for Image transitions when changing the image content
71 | 5. Adding support for custom shapes
72 | 6. ?
73 |
74 | ### License
75 | Copyright 2014 Vinay S Shenoy
76 |
77 | Licensed under the Apache License, Version 2.0 (the "License");
78 | you may not use this file except in compliance with the License.
79 | You may obtain a copy of the License at
80 |
81 | http://www.apache.org/licenses/LICENSE-2.0
82 |
83 | Unless required by applicable law or agreed to in writing, software
84 | distributed under the License is distributed on an "AS IS" BASIS,
85 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86 | See the License for the specific language governing permissions and
87 | limitations under the License.
88 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion '23.0.2'
6 |
7 | /* Required for volley sample */
8 | useLibrary 'org.apache.http.legacy'
9 |
10 | defaultConfig {
11 | applicationId "com.vinaysshenoy.okulusdemo"
12 | minSdkVersion 9
13 | targetSdkVersion 23
14 | versionCode 1
15 | versionName "1.0"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | compile project(':library')
28 | compile 'com.android.support:appcompat-v7:23.1.1'
29 | compile 'com.squareup.picasso:picasso:2.4.0'
30 | compile 'com.github.bumptech.glide:glide:3.4.0'
31 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
32 | }
33 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/vinay.shenoy/Desktop/android-sdk-macosx/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/AuthFailureError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.content.Intent;
20 |
21 | import com.android.volley.NetworkResponse;
22 | import com.android.volley.VolleyError;
23 |
24 | /**
25 | * Error indicating that there was an authentication failure when performing a Request.
26 | */
27 | @SuppressWarnings("serial")
28 | public class AuthFailureError extends VolleyError {
29 | /** An intent that can be used to resolve this exception. (Brings up the password dialog.) */
30 | private Intent mResolutionIntent;
31 |
32 | public AuthFailureError() { }
33 |
34 | public AuthFailureError(Intent intent) {
35 | mResolutionIntent = intent;
36 | }
37 |
38 | public AuthFailureError(NetworkResponse response) {
39 | super(response);
40 | }
41 |
42 | public AuthFailureError(String message) {
43 | super(message);
44 | }
45 |
46 | public AuthFailureError(String message, Exception reason) {
47 | super(message, reason);
48 | }
49 |
50 | public Intent getResolutionIntent() {
51 | return mResolutionIntent;
52 | }
53 |
54 | @Override
55 | public String getMessage() {
56 | if (mResolutionIntent != null) {
57 | return "User needs to (re)enter credentials.";
58 | }
59 | return super.getMessage();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/Cache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import java.util.Collections;
20 | import java.util.Map;
21 |
22 | /**
23 | * An interface for a cache keyed by a String with a byte array as data.
24 | */
25 | public interface Cache {
26 | /**
27 | * Retrieves an entry from the cache.
28 | * @param key Cache key
29 | * @return An {@link com.android.volley.Cache.Entry} or null in the event of a cache miss
30 | */
31 | public Entry get(String key);
32 |
33 | /**
34 | * Adds or replaces an entry to the cache.
35 | * @param key Cache key
36 | * @param entry Data to store and metadata for cache coherency, TTL, etc.
37 | */
38 | public void put(String key, Entry entry);
39 |
40 | /**
41 | * Performs any potentially long-running actions needed to initialize the cache;
42 | * will be called from a worker thread.
43 | */
44 | public void initialize();
45 |
46 | /**
47 | * Invalidates an entry in the cache.
48 | * @param key Cache key
49 | * @param fullExpire True to fully expire the entry, false to soft expire
50 | */
51 | public void invalidate(String key, boolean fullExpire);
52 |
53 | /**
54 | * Removes an entry from the cache.
55 | * @param key Cache key
56 | */
57 | public void remove(String key);
58 |
59 | /**
60 | * Empties the cache.
61 | */
62 | public void clear();
63 |
64 | /**
65 | * Data and metadata for an entry returned by the cache.
66 | */
67 | public static class Entry {
68 | /** The data returned from cache. */
69 | public byte[] data;
70 |
71 | /** ETag for cache coherency. */
72 | public String etag;
73 |
74 | /** Date of this response as reported by the server. */
75 | public long serverDate;
76 |
77 | /** TTL for this record. */
78 | public long ttl;
79 |
80 | /** Soft TTL for this record. */
81 | public long softTtl;
82 |
83 | /** Immutable response headers as received from server; must be non-null. */
84 | public Map responseHeaders = Collections.emptyMap();
85 |
86 | /** True if the entry is expired. */
87 | public boolean isExpired() {
88 | return this.ttl < System.currentTimeMillis();
89 | }
90 |
91 | /** True if a refresh is needed from the original data source. */
92 | public boolean refreshNeeded() {
93 | return this.softTtl < System.currentTimeMillis();
94 | }
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/CacheDispatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.os.Process;
20 |
21 | import java.util.concurrent.BlockingQueue;
22 |
23 | /**
24 | * Provides a thread for performing cache triage on a queue of requests.
25 | *
26 | * Requests added to the specified cache queue are resolved from cache.
27 | * Any deliverable response is posted back to the caller via a
28 | * {@link ResponseDelivery}. Cache misses and responses that require
29 | * refresh are enqueued on the specified network queue for processing
30 | * by a {@link NetworkDispatcher}.
31 | */
32 | public class CacheDispatcher extends Thread {
33 |
34 | private static final boolean DEBUG = VolleyLog.DEBUG;
35 |
36 | /** The queue of requests coming in for triage. */
37 | private final BlockingQueue> mCacheQueue;
38 |
39 | /** The queue of requests going out to the network. */
40 | private final BlockingQueue> mNetworkQueue;
41 |
42 | /** The cache to read from. */
43 | private final Cache mCache;
44 |
45 | /** For posting responses. */
46 | private final ResponseDelivery mDelivery;
47 |
48 | /** Used for telling us to die. */
49 | private volatile boolean mQuit = false;
50 |
51 | /**
52 | * Creates a new cache triage dispatcher thread. You must call {@link #start()}
53 | * in order to begin processing.
54 | *
55 | * @param cacheQueue Queue of incoming requests for triage
56 | * @param networkQueue Queue to post requests that require network to
57 | * @param cache Cache interface to use for resolution
58 | * @param delivery Delivery interface to use for posting responses
59 | */
60 | public CacheDispatcher(
61 | BlockingQueue> cacheQueue, BlockingQueue> networkQueue,
62 | Cache cache, ResponseDelivery delivery) {
63 | mCacheQueue = cacheQueue;
64 | mNetworkQueue = networkQueue;
65 | mCache = cache;
66 | mDelivery = delivery;
67 | }
68 |
69 | /**
70 | * Forces this dispatcher to quit immediately. If any requests are still in
71 | * the queue, they are not guaranteed to be processed.
72 | */
73 | public void quit() {
74 | mQuit = true;
75 | interrupt();
76 | }
77 |
78 | @Override
79 | public void run() {
80 | if (DEBUG) VolleyLog.v("start new dispatcher");
81 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
82 |
83 | // Make a blocking call to initialize the cache.
84 | mCache.initialize();
85 |
86 | while (true) {
87 | try {
88 | // Get a request from the cache triage queue, blocking until
89 | // at least one is available.
90 | final Request> request = mCacheQueue.take();
91 | request.addMarker("cache-queue-take");
92 |
93 | // If the request has been canceled, don't bother dispatching it.
94 | if (request.isCanceled()) {
95 | request.finish("cache-discard-canceled");
96 | continue;
97 | }
98 |
99 | // Attempt to retrieve this item from cache.
100 | Cache.Entry entry = mCache.get(request.getCacheKey());
101 | if (entry == null) {
102 | request.addMarker("cache-miss");
103 | // Cache miss; send off to the network dispatcher.
104 | mNetworkQueue.put(request);
105 | continue;
106 | }
107 |
108 | // If it is completely expired, just send it to the network.
109 | if (entry.isExpired()) {
110 | request.addMarker("cache-hit-expired");
111 | request.setCacheEntry(entry);
112 | mNetworkQueue.put(request);
113 | continue;
114 | }
115 |
116 | // We have a cache hit; parse its data for delivery back to the request.
117 | request.addMarker("cache-hit");
118 | Response> response = request.parseNetworkResponse(
119 | new NetworkResponse(entry.data, entry.responseHeaders));
120 | request.addMarker("cache-hit-parsed");
121 |
122 | if (!entry.refreshNeeded()) {
123 | // Completely unexpired cache hit. Just deliver the response.
124 | mDelivery.postResponse(request, response);
125 | } else {
126 | // Soft-expired cache hit. We can deliver the cached response,
127 | // but we need to also send the request to the network for
128 | // refreshing.
129 | request.addMarker("cache-hit-refresh-needed");
130 | request.setCacheEntry(entry);
131 |
132 | // Mark the response as intermediate.
133 | response.intermediate = true;
134 |
135 | // Post the intermediate response back to the user and have
136 | // the delivery then forward the request along to the network.
137 | mDelivery.postResponse(request, response, new Runnable() {
138 | @Override
139 | public void run() {
140 | try {
141 | mNetworkQueue.put(request);
142 | } catch (InterruptedException e) {
143 | // Not much we can do about this.
144 | }
145 | }
146 | });
147 | }
148 |
149 | } catch (InterruptedException e) {
150 | // We may have been interrupted because it was time to quit.
151 | if (mQuit) {
152 | return;
153 | }
154 | continue;
155 | }
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/DefaultRetryPolicy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Default retry policy for requests.
21 | */
22 | public class DefaultRetryPolicy implements RetryPolicy {
23 | /** The current timeout in milliseconds. */
24 | private int mCurrentTimeoutMs;
25 |
26 | /** The current retry count. */
27 | private int mCurrentRetryCount;
28 |
29 | /** The maximum number of attempts. */
30 | private final int mMaxNumRetries;
31 |
32 | /** The backoff multiplier for the policy. */
33 | private final float mBackoffMultiplier;
34 |
35 | /** The default socket timeout in milliseconds */
36 | public static final int DEFAULT_TIMEOUT_MS = 2500;
37 |
38 | /** The default number of retries */
39 | public static final int DEFAULT_MAX_RETRIES = 1;
40 |
41 | /** The default backoff multiplier */
42 | public static final float DEFAULT_BACKOFF_MULT = 1f;
43 |
44 | /**
45 | * Constructs a new retry policy using the default timeouts.
46 | */
47 | public DefaultRetryPolicy() {
48 | this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT);
49 | }
50 |
51 | /**
52 | * Constructs a new retry policy.
53 | * @param initialTimeoutMs The initial timeout for the policy.
54 | * @param maxNumRetries The maximum number of retries.
55 | * @param backoffMultiplier Backoff multiplier for the policy.
56 | */
57 | public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) {
58 | mCurrentTimeoutMs = initialTimeoutMs;
59 | mMaxNumRetries = maxNumRetries;
60 | mBackoffMultiplier = backoffMultiplier;
61 | }
62 |
63 | /**
64 | * Returns the current timeout.
65 | */
66 | @Override
67 | public int getCurrentTimeout() {
68 | return mCurrentTimeoutMs;
69 | }
70 |
71 | /**
72 | * Returns the current retry count.
73 | */
74 | @Override
75 | public int getCurrentRetryCount() {
76 | return mCurrentRetryCount;
77 | }
78 |
79 | /**
80 | * Returns the backoff multiplier for the policy.
81 | */
82 | public float getBackoffMultiplier() {
83 | return mBackoffMultiplier;
84 | }
85 |
86 | /**
87 | * Prepares for the next retry by applying a backoff to the timeout.
88 | * @param error The error code of the last attempt.
89 | */
90 | @Override
91 | public void retry(VolleyError error) throws VolleyError {
92 | mCurrentRetryCount++;
93 | mCurrentTimeoutMs += (mCurrentTimeoutMs * mBackoffMultiplier);
94 | if (!hasAttemptRemaining()) {
95 | throw error;
96 | }
97 | }
98 |
99 | /**
100 | * Returns true if this policy has attempts remaining, false otherwise.
101 | */
102 | protected boolean hasAttemptRemaining() {
103 | return mCurrentRetryCount <= mMaxNumRetries;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/ExecutorDelivery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.os.Handler;
20 |
21 | import java.util.concurrent.Executor;
22 |
23 | /**
24 | * Delivers responses and errors.
25 | */
26 | public class ExecutorDelivery implements ResponseDelivery {
27 | /** Used for posting responses, typically to the main thread. */
28 | private final Executor mResponsePoster;
29 |
30 | /**
31 | * Creates a new response delivery interface.
32 | * @param handler {@link android.os.Handler} to post responses on
33 | */
34 | public ExecutorDelivery(final Handler handler) {
35 | // Make an Executor that just wraps the handler.
36 | mResponsePoster = new Executor() {
37 | @Override
38 | public void execute(Runnable command) {
39 | handler.post(command);
40 | }
41 | };
42 | }
43 |
44 | /**
45 | * Creates a new response delivery interface, mockable version
46 | * for testing.
47 | * @param executor For running delivery tasks
48 | */
49 | public ExecutorDelivery(Executor executor) {
50 | mResponsePoster = executor;
51 | }
52 |
53 | @Override
54 | public void postResponse(Request> request, Response> response) {
55 | postResponse(request, response, null);
56 | }
57 |
58 | @Override
59 | public void postResponse(Request> request, Response> response, Runnable runnable) {
60 | request.markDelivered();
61 | request.addMarker("post-response");
62 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
63 | }
64 |
65 | @Override
66 | public void postError(Request> request, VolleyError error) {
67 | request.addMarker("post-error");
68 | Response> response = Response.error(error);
69 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
70 | }
71 |
72 | /**
73 | * A Runnable used for delivering network responses to a listener on the
74 | * main thread.
75 | */
76 | @SuppressWarnings("rawtypes")
77 | private class ResponseDeliveryRunnable implements Runnable {
78 | private final Request mRequest;
79 | private final Response mResponse;
80 | private final Runnable mRunnable;
81 |
82 | public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
83 | mRequest = request;
84 | mResponse = response;
85 | mRunnable = runnable;
86 | }
87 |
88 | @SuppressWarnings("unchecked")
89 | @Override
90 | public void run() {
91 | // If this request has canceled, finish it and don't deliver.
92 | if (mRequest.isCanceled()) {
93 | mRequest.finish("canceled-at-delivery");
94 | return;
95 | }
96 |
97 | // Deliver a normal response or error, depending.
98 | if (mResponse.isSuccess()) {
99 | mRequest.deliverResponse(mResponse.result);
100 | } else {
101 | mRequest.deliverError(mResponse.error);
102 | }
103 |
104 | // If this is an intermediate response, add a marker, otherwise we're done
105 | // and the request can be finished.
106 | if (mResponse.intermediate) {
107 | mRequest.addMarker("intermediate-response");
108 | } else {
109 | mRequest.finish("done");
110 | }
111 |
112 | // If we have been provided a post-delivery runnable, run it.
113 | if (mRunnable != null) {
114 | mRunnable.run();
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/Network.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * An interface for performing requests.
21 | */
22 | public interface Network {
23 | /**
24 | * Performs the specified request.
25 | * @param request Request to process
26 | * @return A {@link NetworkResponse} with data and caching metadata; will never be null
27 | * @throws VolleyError on errors
28 | */
29 | public NetworkResponse performRequest(Request> request) throws VolleyError;
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/NetworkDispatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.annotation.TargetApi;
20 | import android.net.TrafficStats;
21 | import android.os.Build;
22 | import android.os.Process;
23 | import android.os.SystemClock;
24 |
25 | import java.util.concurrent.BlockingQueue;
26 |
27 | /**
28 | * Provides a thread for performing network dispatch from a queue of requests.
29 | *
30 | * Requests added to the specified queue are processed from the network via a
31 | * specified {@link com.android.volley.Network} interface. Responses are committed to cache, if
32 | * eligible, using a specified {@link com.android.volley.Cache} interface. Valid responses and
33 | * errors are posted back to the caller via a {@link com.android.volley.ResponseDelivery}.
34 | */
35 | public class NetworkDispatcher extends Thread {
36 | /** The queue of requests to service. */
37 | private final BlockingQueue> mQueue;
38 | /** The network interface for processing requests. */
39 | private final Network mNetwork;
40 | /** The cache to write to. */
41 | private final Cache mCache;
42 | /** For posting responses and errors. */
43 | private final ResponseDelivery mDelivery;
44 | /** Used for telling us to die. */
45 | private volatile boolean mQuit = false;
46 |
47 | /**
48 | * Creates a new network dispatcher thread. You must call {@link #start()}
49 | * in order to begin processing.
50 | *
51 | * @param queue Queue of incoming requests for triage
52 | * @param network Network interface to use for performing requests
53 | * @param cache Cache interface to use for writing responses to cache
54 | * @param delivery Delivery interface to use for posting responses
55 | */
56 | public NetworkDispatcher(BlockingQueue> queue,
57 | Network network, Cache cache,
58 | ResponseDelivery delivery) {
59 | mQueue = queue;
60 | mNetwork = network;
61 | mCache = cache;
62 | mDelivery = delivery;
63 | }
64 |
65 | /**
66 | * Forces this dispatcher to quit immediately. If any requests are still in
67 | * the queue, they are not guaranteed to be processed.
68 | */
69 | public void quit() {
70 | mQuit = true;
71 | interrupt();
72 | }
73 |
74 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
75 | private void addTrafficStatsTag(Request> request) {
76 | // Tag the request (if API >= 14)
77 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
78 | TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
79 | }
80 | }
81 |
82 | @Override
83 | public void run() {
84 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
85 | while (true) {
86 | long startTimeMs = SystemClock.elapsedRealtime();
87 | Request> request;
88 | try {
89 | // Take a request from the queue.
90 | request = mQueue.take();
91 | } catch (InterruptedException e) {
92 | // We may have been interrupted because it was time to quit.
93 | if (mQuit) {
94 | return;
95 | }
96 | continue;
97 | }
98 |
99 | try {
100 | request.addMarker("network-queue-take");
101 |
102 | // If the request was cancelled already, do not perform the
103 | // network request.
104 | if (request.isCanceled()) {
105 | request.finish("network-discard-cancelled");
106 | continue;
107 | }
108 |
109 | addTrafficStatsTag(request);
110 |
111 | // Perform the network request.
112 | NetworkResponse networkResponse = mNetwork.performRequest(request);
113 | request.addMarker("network-http-complete");
114 |
115 | // If the server returned 304 AND we delivered a response already,
116 | // we're done -- don't deliver a second identical response.
117 | if (networkResponse.notModified && request.hasHadResponseDelivered()) {
118 | request.finish("not-modified");
119 | continue;
120 | }
121 |
122 | // Parse the response here on the worker thread.
123 | Response> response = request.parseNetworkResponse(networkResponse);
124 | request.addMarker("network-parse-complete");
125 |
126 | // Write to cache if applicable.
127 | // TODO: Only update cache metadata instead of entire record for 304s.
128 | if (request.shouldCache() && response.cacheEntry != null) {
129 | mCache.put(request.getCacheKey(), response.cacheEntry);
130 | request.addMarker("network-cache-written");
131 | }
132 |
133 | // Post the response back.
134 | request.markDelivered();
135 | mDelivery.postResponse(request, response);
136 | } catch (VolleyError volleyError) {
137 | volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
138 | parseAndDeliverNetworkError(request, volleyError);
139 | } catch (Exception e) {
140 | VolleyLog.e(e, "Unhandled exception %s", e.toString());
141 | VolleyError volleyError = new VolleyError(e);
142 | volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);
143 | mDelivery.postError(request, volleyError);
144 | }
145 | }
146 | }
147 |
148 | private void parseAndDeliverNetworkError(Request> request, VolleyError error) {
149 | error = request.parseNetworkError(error);
150 | mDelivery.postError(request, error);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/NetworkError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import com.android.volley.NetworkResponse;
20 | import com.android.volley.VolleyError;
21 |
22 | /**
23 | * Indicates that there was a network error when performing a Volley request.
24 | */
25 | @SuppressWarnings("serial")
26 | public class NetworkError extends VolleyError {
27 | public NetworkError() {
28 | super();
29 | }
30 |
31 | public NetworkError(Throwable cause) {
32 | super(cause);
33 | }
34 |
35 | public NetworkError(NetworkResponse networkResponse) {
36 | super(networkResponse);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/NetworkResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 |
20 | import org.apache.http.HttpStatus;
21 |
22 | import java.util.Collections;
23 | import java.util.Map;
24 |
25 | /**
26 | * Data and headers returned from {@link com.android.volley.Network#performRequest(com.android.volley.Request)}.
27 | */
28 | public class NetworkResponse {
29 | /**
30 | * Creates a new network response.
31 | * @param statusCode the HTTP status code
32 | * @param data Response body
33 | * @param headers Headers returned with this response, or null for none
34 | * @param notModified True if the server returned a 304 and the data was already in cache
35 | * @param networkTimeMs Round-trip network time to receive network response
36 | */
37 | public NetworkResponse(int statusCode, byte[] data, Map headers,
38 | boolean notModified, long networkTimeMs) {
39 | this.statusCode = statusCode;
40 | this.data = data;
41 | this.headers = headers;
42 | this.notModified = notModified;
43 | this.networkTimeMs = networkTimeMs;
44 | }
45 |
46 | public NetworkResponse(int statusCode, byte[] data, Map headers,
47 | boolean notModified) {
48 | this(statusCode, data, headers, notModified, 0);
49 | }
50 |
51 | public NetworkResponse(byte[] data) {
52 | this(HttpStatus.SC_OK, data, Collections.emptyMap(), false, 0);
53 | }
54 |
55 | public NetworkResponse(byte[] data, Map headers) {
56 | this(HttpStatus.SC_OK, data, headers, false, 0);
57 | }
58 |
59 | /** The HTTP status code. */
60 | public final int statusCode;
61 |
62 | /** Raw data from this response. */
63 | public final byte[] data;
64 |
65 | /** Response headers. */
66 | public final Map headers;
67 |
68 | /** True if the server returned a 304 (Not Modified). */
69 | public final boolean notModified;
70 |
71 | /** Network roundtrip time in milliseconds. */
72 | public final long networkTimeMs;
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/NoConnectionError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Error indicating that no connection could be established when performing a Volley request.
21 | */
22 | @SuppressWarnings("serial")
23 | public class NoConnectionError extends NetworkError {
24 | public NoConnectionError() {
25 | super();
26 | }
27 |
28 | public NoConnectionError(Throwable reason) {
29 | super(reason);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/ParseError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import com.android.volley.NetworkResponse;
20 | import com.android.volley.VolleyError;
21 |
22 | /**
23 | * Indicates that the server's response could not be parsed.
24 | */
25 | @SuppressWarnings("serial")
26 | public class ParseError extends VolleyError {
27 | public ParseError() { }
28 |
29 | public ParseError(NetworkResponse networkResponse) {
30 | super(networkResponse);
31 | }
32 |
33 | public ParseError(Throwable cause) {
34 | super(cause);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/RequestQueue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.os.Handler;
20 | import android.os.Looper;
21 |
22 | import java.util.HashMap;
23 | import java.util.HashSet;
24 | import java.util.LinkedList;
25 | import java.util.Map;
26 | import java.util.Queue;
27 | import java.util.Set;
28 | import java.util.concurrent.PriorityBlockingQueue;
29 | import java.util.concurrent.atomic.AtomicInteger;
30 |
31 | /**
32 | * A request dispatch queue with a thread pool of dispatchers.
33 | *
34 | * Calling {@link #add(com.android.volley.Request)} will enqueue the given Request for dispatch,
35 | * resolving from either cache or network on a worker thread, and then delivering
36 | * a parsed response on the main thread.
37 | */
38 | public class RequestQueue {
39 |
40 | /** Used for generating monotonically-increasing sequence numbers for requests. */
41 | private AtomicInteger mSequenceGenerator = new AtomicInteger();
42 |
43 | /**
44 | * Staging area for requests that already have a duplicate request in flight.
45 | *
46 | *
47 | *
containsKey(cacheKey) indicates that there is a request in flight for the given cache
48 | * key.
49 | *
get(cacheKey) returns waiting requests for the given cache key. The in flight request
50 | * is not contained in that list. Is null if no requests are staged.
51 | *
52 | */
53 | private final Map>> mWaitingRequests =
54 | new HashMap>>();
55 |
56 | /**
57 | * The set of all requests currently being processed by this RequestQueue. A Request
58 | * will be in this set if it is waiting in any queue or currently being processed by
59 | * any dispatcher.
60 | */
61 | private final Set> mCurrentRequests = new HashSet>();
62 |
63 | /** The cache triage queue. */
64 | private final PriorityBlockingQueue> mCacheQueue =
65 | new PriorityBlockingQueue>();
66 |
67 | /** The queue of requests that are actually going out to the network. */
68 | private final PriorityBlockingQueue> mNetworkQueue =
69 | new PriorityBlockingQueue>();
70 |
71 | /** Number of network request dispatcher threads to start. */
72 | private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4;
73 |
74 | /** Cache interface for retrieving and storing responses. */
75 | private final Cache mCache;
76 |
77 | /** Network interface for performing requests. */
78 | private final Network mNetwork;
79 |
80 | /** Response delivery mechanism. */
81 | private final ResponseDelivery mDelivery;
82 |
83 | /** The network dispatchers. */
84 | private NetworkDispatcher[] mDispatchers;
85 |
86 | /** The cache dispatcher. */
87 | private CacheDispatcher mCacheDispatcher;
88 |
89 | /**
90 | * Creates the worker pool. Processing will not begin until {@link #start()} is called.
91 | *
92 | * @param cache A Cache to use for persisting responses to disk
93 | * @param network A Network interface for performing HTTP requests
94 | * @param threadPoolSize Number of network dispatcher threads to create
95 | * @param delivery A ResponseDelivery interface for posting responses and errors
96 | */
97 | public RequestQueue(Cache cache, Network network, int threadPoolSize,
98 | ResponseDelivery delivery) {
99 | mCache = cache;
100 | mNetwork = network;
101 | mDispatchers = new NetworkDispatcher[threadPoolSize];
102 | mDelivery = delivery;
103 | }
104 |
105 | /**
106 | * Creates the worker pool. Processing will not begin until {@link #start()} is called.
107 | *
108 | * @param cache A Cache to use for persisting responses to disk
109 | * @param network A Network interface for performing HTTP requests
110 | * @param threadPoolSize Number of network dispatcher threads to create
111 | */
112 | public RequestQueue(Cache cache, Network network, int threadPoolSize) {
113 | this(cache, network, threadPoolSize,
114 | new ExecutorDelivery(new Handler(Looper.getMainLooper())));
115 | }
116 |
117 | /**
118 | * Creates the worker pool. Processing will not begin until {@link #start()} is called.
119 | *
120 | * @param cache A Cache to use for persisting responses to disk
121 | * @param network A Network interface for performing HTTP requests
122 | */
123 | public RequestQueue(Cache cache, Network network) {
124 | this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
125 | }
126 |
127 | /**
128 | * Starts the dispatchers in this queue.
129 | */
130 | public void start() {
131 | stop(); // Make sure any currently running dispatchers are stopped.
132 | // Create the cache dispatcher and start it.
133 | mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
134 | mCacheDispatcher.start();
135 |
136 | // Create network dispatchers (and corresponding threads) up to the pool size.
137 | for (int i = 0; i < mDispatchers.length; i++) {
138 | NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
139 | mCache, mDelivery);
140 | mDispatchers[i] = networkDispatcher;
141 | networkDispatcher.start();
142 | }
143 | }
144 |
145 | /**
146 | * Stops the cache and network dispatchers.
147 | */
148 | public void stop() {
149 | if (mCacheDispatcher != null) {
150 | mCacheDispatcher.quit();
151 | }
152 | for (int i = 0; i < mDispatchers.length; i++) {
153 | if (mDispatchers[i] != null) {
154 | mDispatchers[i].quit();
155 | }
156 | }
157 | }
158 |
159 | /**
160 | * Gets a sequence number.
161 | */
162 | public int getSequenceNumber() {
163 | return mSequenceGenerator.incrementAndGet();
164 | }
165 |
166 | /**
167 | * Gets the {@link com.android.volley.Cache} instance being used.
168 | */
169 | public Cache getCache() {
170 | return mCache;
171 | }
172 |
173 | /**
174 | * A simple predicate or filter interface for Requests, for use by
175 | * {@link com.android.volley.RequestQueue#cancelAll(com.android.volley.RequestQueue.RequestFilter)}.
176 | */
177 | public interface RequestFilter {
178 | public boolean apply(Request> request);
179 | }
180 |
181 | /**
182 | * Cancels all requests in this queue for which the given filter applies.
183 | * @param filter The filtering function to use
184 | */
185 | public void cancelAll(RequestFilter filter) {
186 | synchronized (mCurrentRequests) {
187 | for (Request> request : mCurrentRequests) {
188 | if (filter.apply(request)) {
189 | request.cancel();
190 | }
191 | }
192 | }
193 | }
194 |
195 | /**
196 | * Cancels all requests in this queue with the given tag. Tag must be non-null
197 | * and equality is by identity.
198 | */
199 | public void cancelAll(final Object tag) {
200 | if (tag == null) {
201 | throw new IllegalArgumentException("Cannot cancelAll with a null tag");
202 | }
203 | cancelAll(new RequestFilter() {
204 | @Override
205 | public boolean apply(Request> request) {
206 | return request.getTag() == tag;
207 | }
208 | });
209 | }
210 |
211 | /**
212 | * Adds a Request to the dispatch queue.
213 | * @param request The request to service
214 | * @return The passed-in request
215 | */
216 | public Request add(Request request) {
217 | // Tag the request as belonging to this queue and add it to the set of current requests.
218 | request.setRequestQueue(this);
219 | synchronized (mCurrentRequests) {
220 | mCurrentRequests.add(request);
221 | }
222 |
223 | // Process requests in the order they are added.
224 | request.setSequence(getSequenceNumber());
225 | request.addMarker("add-to-queue");
226 |
227 | // If the request is uncacheable, skip the cache queue and go straight to the network.
228 | if (!request.shouldCache()) {
229 | mNetworkQueue.add(request);
230 | return request;
231 | }
232 |
233 | // Insert request into stage if there's already a request with the same cache key in flight.
234 | synchronized (mWaitingRequests) {
235 | String cacheKey = request.getCacheKey();
236 | if (mWaitingRequests.containsKey(cacheKey)) {
237 | // There is already a request in flight. Queue up.
238 | Queue> stagedRequests = mWaitingRequests.get(cacheKey);
239 | if (stagedRequests == null) {
240 | stagedRequests = new LinkedList>();
241 | }
242 | stagedRequests.add(request);
243 | mWaitingRequests.put(cacheKey, stagedRequests);
244 | if (VolleyLog.DEBUG) {
245 | VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);
246 | }
247 | } else {
248 | // Insert 'null' queue for this cacheKey, indicating there is now a request in
249 | // flight.
250 | mWaitingRequests.put(cacheKey, null);
251 | mCacheQueue.add(request);
252 | }
253 | return request;
254 | }
255 | }
256 |
257 | /**
258 | * Called from {@link com.android.volley.Request#finish(String)}, indicating that processing of the given request
259 | * has finished.
260 | *
261 | *
Releases waiting requests for request.getCacheKey() if
262 | * request.shouldCache().
263 | */
264 | void finish(Request> request) {
265 | // Remove from the set of requests currently being processed.
266 | synchronized (mCurrentRequests) {
267 | mCurrentRequests.remove(request);
268 | }
269 |
270 | if (request.shouldCache()) {
271 | synchronized (mWaitingRequests) {
272 | String cacheKey = request.getCacheKey();
273 | Queue> waitingRequests = mWaitingRequests.remove(cacheKey);
274 | if (waitingRequests != null) {
275 | if (VolleyLog.DEBUG) {
276 | VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.",
277 | waitingRequests.size(), cacheKey);
278 | }
279 | // Process all queued up requests. They won't be considered as in flight, but
280 | // that's not a problem as the cache has been primed by 'request'.
281 | mCacheQueue.addAll(waitingRequests);
282 | }
283 | }
284 | }
285 | }
286 | }
287 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/Response.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Encapsulates a parsed response for delivery.
21 | *
22 | * @param Parsed type of this response
23 | */
24 | public class Response {
25 |
26 | /** Callback interface for delivering parsed responses. */
27 | public interface Listener {
28 | /** Called when a response is received. */
29 | public void onResponse(T response);
30 | }
31 |
32 | /** Callback interface for delivering error responses. */
33 | public interface ErrorListener {
34 | /**
35 | * Callback method that an error has been occurred with the
36 | * provided error code and optional user-readable message.
37 | */
38 | public void onErrorResponse(VolleyError error);
39 | }
40 |
41 | /** Returns a successful response containing the parsed result. */
42 | public static Response success(T result, Cache.Entry cacheEntry) {
43 | return new Response(result, cacheEntry);
44 | }
45 |
46 | /**
47 | * Returns a failed response containing the given error code and an optional
48 | * localized message displayed to the user.
49 | */
50 | public static Response error(VolleyError error) {
51 | return new Response(error);
52 | }
53 |
54 | /** Parsed response, or null in the case of error. */
55 | public final T result;
56 |
57 | /** Cache metadata for this response, or null in the case of error. */
58 | public final Cache.Entry cacheEntry;
59 |
60 | /** Detailed error information if errorCode != OK. */
61 | public final VolleyError error;
62 |
63 | /** True if this response was a soft-expired one and a second one MAY be coming. */
64 | public boolean intermediate = false;
65 |
66 | /**
67 | * Returns whether this response is considered successful.
68 | */
69 | public boolean isSuccess() {
70 | return error == null;
71 | }
72 |
73 |
74 | private Response(T result, Cache.Entry cacheEntry) {
75 | this.result = result;
76 | this.cacheEntry = cacheEntry;
77 | this.error = null;
78 | }
79 |
80 | private Response(VolleyError error) {
81 | this.result = null;
82 | this.cacheEntry = null;
83 | this.error = error;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/ResponseDelivery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | public interface ResponseDelivery {
20 | /**
21 | * Parses a response from the network or cache and delivers it.
22 | */
23 | public void postResponse(Request> request, Response> response);
24 |
25 | /**
26 | * Parses a response from the network or cache and delivers it. The provided
27 | * Runnable will be executed after delivery.
28 | */
29 | public void postResponse(Request> request, Response> response, Runnable runnable);
30 |
31 | /**
32 | * Posts an error for the given request.
33 | */
34 | public void postError(Request> request, VolleyError error);
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/RetryPolicy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Retry policy for a request.
21 | */
22 | public interface RetryPolicy {
23 |
24 | /**
25 | * Returns the current timeout (used for logging).
26 | */
27 | public int getCurrentTimeout();
28 |
29 | /**
30 | * Returns the current retry count (used for logging).
31 | */
32 | public int getCurrentRetryCount();
33 |
34 | /**
35 | * Prepares for the next retry by applying a backoff to the timeout.
36 | * @param error The error code of the last attempt.
37 | * @throws VolleyError In the event that the retry could not be performed (for example if we
38 | * ran out of attempts), the passed in error is thrown.
39 | */
40 | public void retry(VolleyError error) throws VolleyError;
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/ServerError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import com.android.volley.NetworkResponse;
20 | import com.android.volley.VolleyError;
21 |
22 | /**
23 | * Indicates that the server responded with an error response.
24 | */
25 | @SuppressWarnings("serial")
26 | public class ServerError extends VolleyError {
27 | public ServerError(NetworkResponse networkResponse) {
28 | super(networkResponse);
29 | }
30 |
31 | public ServerError() {
32 | super();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/TimeoutError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Indicates that the connection or the socket timed out.
21 | */
22 | @SuppressWarnings("serial")
23 | public class TimeoutError extends VolleyError { }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/VolleyError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | /**
20 | * Exception style class encapsulating Volley errors
21 | */
22 | @SuppressWarnings("serial")
23 | public class VolleyError extends Exception {
24 | public final NetworkResponse networkResponse;
25 | private long networkTimeMs;
26 |
27 | public VolleyError() {
28 | networkResponse = null;
29 | }
30 |
31 | public VolleyError(NetworkResponse response) {
32 | networkResponse = response;
33 | }
34 |
35 | public VolleyError(String exceptionMessage) {
36 | super(exceptionMessage);
37 | networkResponse = null;
38 | }
39 |
40 | public VolleyError(String exceptionMessage, Throwable reason) {
41 | super(exceptionMessage, reason);
42 | networkResponse = null;
43 | }
44 |
45 | public VolleyError(Throwable cause) {
46 | super(cause);
47 | networkResponse = null;
48 | }
49 |
50 | /* package */ void setNetworkTimeMs(long networkTimeMs) {
51 | this.networkTimeMs = networkTimeMs;
52 | }
53 |
54 | public long getNetworkTimeMs() {
55 | return networkTimeMs;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/VolleyLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley;
18 |
19 | import android.os.SystemClock;
20 | import android.util.Log;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 | import java.util.Locale;
25 |
26 | /** Logging helper class. */
27 | public class VolleyLog {
28 | public static String TAG = "Volley";
29 |
30 | public static boolean DEBUG = Log.isLoggable(TAG, Log.VERBOSE);
31 |
32 | /**
33 | * Customize the log tag for your application, so that other apps
34 | * using Volley don't mix their logs with yours.
35 | *
36 | * Enable the log property for your tag before starting your app:
37 | *
38 | * {@code adb shell setprop log.tag.<tag>}
39 | */
40 | public static void setTag(String tag) {
41 | d("Changing log tag to %s", tag);
42 | TAG = tag;
43 |
44 | // Reinitialize the DEBUG "constant"
45 | DEBUG = Log.isLoggable(TAG, Log.VERBOSE);
46 | }
47 |
48 | public static void v(String format, Object... args) {
49 | if (DEBUG) {
50 | Log.v(TAG, buildMessage(format, args));
51 | }
52 | }
53 |
54 | public static void d(String format, Object... args) {
55 | Log.d(TAG, buildMessage(format, args));
56 | }
57 |
58 | public static void e(String format, Object... args) {
59 | Log.e(TAG, buildMessage(format, args));
60 | }
61 |
62 | public static void e(Throwable tr, String format, Object... args) {
63 | Log.e(TAG, buildMessage(format, args), tr);
64 | }
65 |
66 | public static void wtf(String format, Object... args) {
67 | Log.wtf(TAG, buildMessage(format, args));
68 | }
69 |
70 | public static void wtf(Throwable tr, String format, Object... args) {
71 | Log.wtf(TAG, buildMessage(format, args), tr);
72 | }
73 |
74 | /**
75 | * Formats the caller's provided message and prepends useful info like
76 | * calling thread ID and method name.
77 | */
78 | private static String buildMessage(String format, Object... args) {
79 | String msg = (args == null) ? format : String.format(Locale.US, format, args);
80 | StackTraceElement[] trace = new Throwable().fillInStackTrace().getStackTrace();
81 |
82 | String caller = "";
83 | // Walk up the stack looking for the first caller outside of VolleyLog.
84 | // It will be at least two frames up, so start there.
85 | for (int i = 2; i < trace.length; i++) {
86 | Class> clazz = trace[i].getClass();
87 | if (!clazz.equals(VolleyLog.class)) {
88 | String callingClass = trace[i].getClassName();
89 | callingClass = callingClass.substring(callingClass.lastIndexOf('.') + 1);
90 | callingClass = callingClass.substring(callingClass.lastIndexOf('$') + 1);
91 |
92 | caller = callingClass + "." + trace[i].getMethodName();
93 | break;
94 | }
95 | }
96 | return String.format(Locale.US, "[%d] %s: %s",
97 | Thread.currentThread().getId(), caller, msg);
98 | }
99 |
100 | /**
101 | * A simple event log with records containing a name, thread ID, and timestamp.
102 | */
103 | static class MarkerLog {
104 | public static final boolean ENABLED = VolleyLog.DEBUG;
105 |
106 | /** Minimum duration from first marker to last in an marker log to warrant logging. */
107 | private static final long MIN_DURATION_FOR_LOGGING_MS = 0;
108 |
109 | private static class Marker {
110 | public final String name;
111 | public final long thread;
112 | public final long time;
113 |
114 | public Marker(String name, long thread, long time) {
115 | this.name = name;
116 | this.thread = thread;
117 | this.time = time;
118 | }
119 | }
120 |
121 | private final List mMarkers = new ArrayList();
122 | private boolean mFinished = false;
123 |
124 | /** Adds a marker to this log with the specified name. */
125 | public synchronized void add(String name, long threadId) {
126 | if (mFinished) {
127 | throw new IllegalStateException("Marker added to finished log");
128 | }
129 |
130 | mMarkers.add(new Marker(name, threadId, SystemClock.elapsedRealtime()));
131 | }
132 |
133 | /**
134 | * Closes the log, dumping it to logcat if the time difference between
135 | * the first and last markers is greater than {@link #MIN_DURATION_FOR_LOGGING_MS}.
136 | * @param header Header string to print above the marker log.
137 | */
138 | public synchronized void finish(String header) {
139 | mFinished = true;
140 |
141 | long duration = getTotalDuration();
142 | if (duration <= MIN_DURATION_FOR_LOGGING_MS) {
143 | return;
144 | }
145 |
146 | long prevTime = mMarkers.get(0).time;
147 | d("(%-4d ms) %s", duration, header);
148 | for (Marker marker : mMarkers) {
149 | long thisTime = marker.time;
150 | d("(+%-4d) [%2d] %s", (thisTime - prevTime), marker.thread, marker.name);
151 | prevTime = thisTime;
152 | }
153 | }
154 |
155 | @Override
156 | protected void finalize() throws Throwable {
157 | // Catch requests that have been collected (and hence end-of-lifed)
158 | // but had no debugging output printed for them.
159 | if (!mFinished) {
160 | finish("Request on the loose");
161 | e("Marker log finalized without finish() - uncaught exit point for request");
162 | }
163 | }
164 |
165 | /** Returns the time difference between the first and last events in this log. */
166 | private long getTotalDuration() {
167 | if (mMarkers.size() == 0) {
168 | return 0;
169 | }
170 |
171 | long first = mMarkers.get(0).time;
172 | long last = mMarkers.get(mMarkers.size() - 1).time;
173 | return last - first;
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/toolbox/AndroidAuthenticator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley.toolbox;
18 |
19 | import com.android.volley.AuthFailureError;
20 |
21 | import android.accounts.Account;
22 | import android.accounts.AccountManager;
23 | import android.accounts.AccountManagerFuture;
24 | import android.content.Context;
25 | import android.content.Intent;
26 | import android.os.Bundle;
27 |
28 | /**
29 | * An Authenticator that uses {@link android.accounts.AccountManager} to get auth
30 | * tokens of a specified type for a specified account.
31 | */
32 | public class AndroidAuthenticator implements Authenticator {
33 | private final Context mContext;
34 | private final Account mAccount;
35 | private final String mAuthTokenType;
36 | private final boolean mNotifyAuthFailure;
37 |
38 | /**
39 | * Creates a new authenticator.
40 | * @param context Context for accessing AccountManager
41 | * @param account Account to authenticate as
42 | * @param authTokenType Auth token type passed to AccountManager
43 | */
44 | public AndroidAuthenticator(Context context, Account account, String authTokenType) {
45 | this(context, account, authTokenType, false);
46 | }
47 |
48 | /**
49 | * Creates a new authenticator.
50 | * @param context Context for accessing AccountManager
51 | * @param account Account to authenticate as
52 | * @param authTokenType Auth token type passed to AccountManager
53 | * @param notifyAuthFailure Whether to raise a notification upon auth failure
54 | */
55 | public AndroidAuthenticator(Context context, Account account, String authTokenType,
56 | boolean notifyAuthFailure) {
57 | mContext = context;
58 | mAccount = account;
59 | mAuthTokenType = authTokenType;
60 | mNotifyAuthFailure = notifyAuthFailure;
61 | }
62 |
63 | /**
64 | * Returns the Account being used by this authenticator.
65 | */
66 | public Account getAccount() {
67 | return mAccount;
68 | }
69 |
70 | // TODO: Figure out what to do about notifyAuthFailure
71 | @SuppressWarnings("deprecation")
72 | @Override
73 | public String getAuthToken() throws AuthFailureError {
74 | final AccountManager accountManager = AccountManager.get(mContext);
75 | AccountManagerFuture future = accountManager.getAuthToken(mAccount,
76 | mAuthTokenType, mNotifyAuthFailure, null, null);
77 | Bundle result;
78 | try {
79 | result = future.getResult();
80 | } catch (Exception e) {
81 | throw new AuthFailureError("Error while retrieving auth token", e);
82 | }
83 | String authToken = null;
84 | if (future.isDone() && !future.isCancelled()) {
85 | if (result.containsKey(AccountManager.KEY_INTENT)) {
86 | Intent intent = result.getParcelable(AccountManager.KEY_INTENT);
87 | throw new AuthFailureError(intent);
88 | }
89 | authToken = result.getString(AccountManager.KEY_AUTHTOKEN);
90 | }
91 | if (authToken == null) {
92 | throw new AuthFailureError("Got null auth token for type: " + mAuthTokenType);
93 | }
94 |
95 | return authToken;
96 | }
97 |
98 | @Override
99 | public void invalidateAuthToken(String authToken) {
100 | AccountManager.get(mContext).invalidateAuthToken(mAccount.type, authToken);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/toolbox/Authenticator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley.toolbox;
18 |
19 | import com.android.volley.AuthFailureError;
20 |
21 | /**
22 | * An interface for interacting with auth tokens.
23 | */
24 | public interface Authenticator {
25 | /**
26 | * Synchronously retrieves an auth token.
27 | *
28 | * @throws AuthFailureError If authentication did not succeed
29 | */
30 | public String getAuthToken() throws AuthFailureError;
31 |
32 | /**
33 | * Invalidates the provided auth token.
34 | */
35 | public void invalidateAuthToken(String authToken);
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/toolbox/ByteArrayPool.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley.toolbox;
18 |
19 | import java.util.ArrayList;
20 | import java.util.Collections;
21 | import java.util.Comparator;
22 | import java.util.LinkedList;
23 | import java.util.List;
24 |
25 | /**
26 | * ByteArrayPool is a source and repository of byte[] objects. Its purpose is to
27 | * supply those buffers to consumers who need to use them for a short period of time and then
28 | * dispose of them. Simply creating and disposing such buffers in the conventional manner can
29 | * considerable heap churn and garbage collection delays on Android, which lacks good management of
30 | * short-lived heap objects. It may be advantageous to trade off some memory in the form of a
31 | * permanently allocated pool of buffers in order to gain heap performance improvements; that is
32 | * what this class does.
33 | *
34 | * A good candidate user for this class is something like an I/O system that uses large temporary
35 | * byte[] buffers to copy data around. In these use cases, often the consumer wants
36 | * the buffer to be a certain minimum size to ensure good performance (e.g. when copying data chunks
37 | * off of a stream), but doesn't mind if the buffer is larger than the minimum. Taking this into
38 | * account and also to maximize the odds of being able to reuse a recycled buffer, this class is
39 | * free to return buffers larger than the requested size. The caller needs to be able to gracefully
40 | * deal with getting buffers any size over the minimum.
41 | *
42 | * If there is not a suitably-sized buffer in its recycling pool when a buffer is requested, this
43 | * class will allocate a new buffer and return it.
44 | *
45 | * This class has no special ownership of buffers it creates; the caller is free to take a buffer
46 | * it receives from this pool, use it permanently, and never return it to the pool; additionally,
47 | * it is not harmful to return to this pool a buffer that was allocated elsewhere, provided there
48 | * are no other lingering references to it.
49 | *
50 | * This class ensures that the total size of the buffers in its recycling pool never exceeds a
51 | * certain byte limit. When a buffer is returned that would cause the pool to exceed the limit,
52 | * least-recently-used buffers are disposed.
53 | */
54 | public class ByteArrayPool {
55 | /** The buffer pool, arranged both by last use and by buffer size */
56 | private List mBuffersByLastUse = new LinkedList();
57 | private List mBuffersBySize = new ArrayList(64);
58 |
59 | /** The total size of the buffers in the pool */
60 | private int mCurrentSize = 0;
61 |
62 | /**
63 | * The maximum aggregate size of the buffers in the pool. Old buffers are discarded to stay
64 | * under this limit.
65 | */
66 | private final int mSizeLimit;
67 |
68 | /** Compares buffers by size */
69 | protected static final Comparator BUF_COMPARATOR = new Comparator() {
70 | @Override
71 | public int compare(byte[] lhs, byte[] rhs) {
72 | return lhs.length - rhs.length;
73 | }
74 | };
75 |
76 | /**
77 | * @param sizeLimit the maximum size of the pool, in bytes
78 | */
79 | public ByteArrayPool(int sizeLimit) {
80 | mSizeLimit = sizeLimit;
81 | }
82 |
83 | /**
84 | * Returns a buffer from the pool if one is available in the requested size, or allocates a new
85 | * one if a pooled one is not available.
86 | *
87 | * @param len the minimum size, in bytes, of the requested buffer. The returned buffer may be
88 | * larger.
89 | * @return a byte[] buffer is always returned.
90 | */
91 | public synchronized byte[] getBuf(int len) {
92 | for (int i = 0; i < mBuffersBySize.size(); i++) {
93 | byte[] buf = mBuffersBySize.get(i);
94 | if (buf.length >= len) {
95 | mCurrentSize -= buf.length;
96 | mBuffersBySize.remove(i);
97 | mBuffersByLastUse.remove(buf);
98 | return buf;
99 | }
100 | }
101 | return new byte[len];
102 | }
103 |
104 | /**
105 | * Returns a buffer to the pool, throwing away old buffers if the pool would exceed its allotted
106 | * size.
107 | *
108 | * @param buf the buffer to return to the pool.
109 | */
110 | public synchronized void returnBuf(byte[] buf) {
111 | if (buf == null || buf.length > mSizeLimit) {
112 | return;
113 | }
114 | mBuffersByLastUse.add(buf);
115 | int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR);
116 | if (pos < 0) {
117 | pos = -pos - 1;
118 | }
119 | mBuffersBySize.add(pos, buf);
120 | mCurrentSize += buf.length;
121 | trim();
122 | }
123 |
124 | /**
125 | * Removes buffers from the pool until it is under its size limit.
126 | */
127 | private synchronized void trim() {
128 | while (mCurrentSize > mSizeLimit) {
129 | byte[] buf = mBuffersByLastUse.remove(0);
130 | mBuffersBySize.remove(buf);
131 | mCurrentSize -= buf.length;
132 | }
133 | }
134 |
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/volley/toolbox/ClearCacheRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.android.volley.toolbox;
18 |
19 | import com.android.volley.Cache;
20 | import com.android.volley.NetworkResponse;
21 | import com.android.volley.Request;
22 | import com.android.volley.Response;
23 |
24 | import android.os.Handler;
25 | import android.os.Looper;
26 |
27 | /**
28 | * A synthetic request used for clearing the cache.
29 | */
30 | public class ClearCacheRequest extends Request