From 1a89ae4cdcf8d467e5d081234ec66a097045f772 Mon Sep 17 00:00:00 2001 From: Katie McCormick Date: Tue, 18 Mar 2014 17:13:50 -0700 Subject: [PATCH] Doc update: new Volley class Change-Id: Ife3a9a64439e07aaaf92a22adc6d1678138caf7d --- "\\" | 19 + docs/html/images/training/volley-request.png | Bin 0 -> 61812 bytes .../training/basics/network-ops/connecting.jd | 1 + .../html/training/basics/network-ops/index.jd | 9 + docs/html/training/training_toc.cs | 29 + docs/html/training/volley/index.jd | 133 + docs/html/training/volley/request-custom.jd | 163 ++ docs/html/training/volley/request.jd | 281 ++ docs/html/training/volley/requestqueue.jd | 204 ++ docs/html/training/volley/simple.jd | 169 ++ .../training/volley/volley-request.graffle | 2259 +++++++++++++++++ 11 files changed, 3267 insertions(+) create mode 100644 "\\" create mode 100644 docs/html/images/training/volley-request.png create mode 100644 docs/html/training/volley/index.jd create mode 100644 docs/html/training/volley/request-custom.jd create mode 100644 docs/html/training/volley/request.jd create mode 100644 docs/html/training/volley/requestqueue.jd create mode 100644 docs/html/training/volley/simple.jd create mode 100644 docs/image_sources/training/volley/volley-request.graffle diff --git "a/\\" "b/\\" new file mode 100644 index 0000000000000..1d25d33b4d33a --- /dev/null +++ "b/\\" @@ -0,0 +1,19 @@ +Doc update: new Volley class + +Change-Id: Ife3a9a64439e07aaaf92a22adc6d1678138caf7d + +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# On branch volley +# Changes to be committed: +# new file: docs/html/images/training/volley-request.png +# modified: docs/html/training/basics/network-ops/connecting.jd +# modified: docs/html/training/basics/network-ops/index.jd +# modified: docs/html/training/training_toc.cs +# new file: docs/html/training/volley/index.jd +# new file: docs/html/training/volley/request-custom.jd +# new file: docs/html/training/volley/request.jd +# new file: docs/html/training/volley/requestqueue.jd +# new file: docs/html/training/volley/setup.jd +# new file: docs/html/training/volley/simple.jd +# diff --git a/docs/html/images/training/volley-request.png b/docs/html/images/training/volley-request.png new file mode 100644 index 0000000000000000000000000000000000000000..85f0681b0f6d8352cb174fc87ef9fe32449d3928 GIT binary patch literal 61812 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 JTuArV{{r`_l=A=p literal 0 HcmV?d00001 diff --git a/docs/html/training/basics/network-ops/connecting.jd b/docs/html/training/basics/network-ops/connecting.jd index 50a9e1bb22272..1452ded925f0b 100644 --- a/docs/html/training/basics/network-ops/connecting.jd +++ b/docs/html/training/basics/network-ops/connecting.jd @@ -25,6 +25,7 @@ next.link=managing.html

You should also read

@@ -51,6 +52,14 @@ as a source of reusable code for your own application.

fundamental building blocks for creating Android applications that download content and parse data efficiently, while minimizing network traffic.

+

Note: See the class Transmitting Network Data Using Volley +for information on Volley, an HTTP library that makes networking for Android apps +easier and faster. Volley is available through the open +AOSP +repository. Volley may be able to help you streamline and improve the performance +of your app's network operations.

+

Lessons

diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 0616b62f01b69..c5dc3c5f76153 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -609,6 +609,35 @@ include the action bar on devices running Android 2.1 or higher." + diff --git a/docs/html/training/volley/index.jd b/docs/html/training/volley/index.jd new file mode 100644 index 0000000000000..ba5b09f8ca3a1 --- /dev/null +++ b/docs/html/training/volley/index.jd @@ -0,0 +1,133 @@ +page.title=Transmitting Network Data Using Volley +page.tags="" + +trainingnavtop=true +startpage=true + + +@jd:body + + + +
+
+ + + +

Dependencies and prerequisites

+ +
    +
  • Android 1.6 (API Level 4) or higher
  • +
+ +

You should also see

+ + +
+
+ + +
+

Video

+

Volley: Easy, Fast Networking for Android

+
+
+ + +

Volley is an HTTP library that makes networking for Android apps easier and most importantly, +faster. Volley is available through the open +AOSP repository.

+ +

Volley offers the following benefits:

+ +
    + +
  • Automatic scheduling of network requests.
  • +
  • Multiple concurrent network connections.
  • +
  • Transparent disk and memory response caching with standard HTTP +cache coherence.
  • +
  • Support for request prioritization.
  • +
  • Cancellation request API. You can cancel a single request, or you can set blocks or +scopes of requests to cancel.
  • +
  • Ease of customization, for example, for retry and backoff.
  • +
  • Strong ordering that makes it easy to correctly populate your UI with data fetched +asynchronously from the network.
  • +
  • Debugging and tracing tools.
  • + +
+ +

Volley excels at RPC-type operations used to populate a UI, such as fetching a page of +search results as structured data. It integrates easily with any protocol and comes out of +the box with support for raw strings, images, and JSON. By providing built-in support for +the features you need, Volley frees you from writing boilerplate code and allows you to +concentrate on the logic that is specific to your app.

+

Volley is not suitable for large download or streaming operations, since Volley holds +all responses in memory during parsing. For large download operations, consider using an +alternative like {@link android.app.DownloadManager}.

+ +

The core Volley library is developed in the open +AOSP +repository at {@code frameworks/volley} and contains the main request dispatch pipeline +as well as a set of commonly applicable utilities, available in the Volley "toolbox." The +easiest way to add Volley to your project is to clone the Volley repository and set it as +a library project:

+ +
    +
  1. Git clone the repository by typing the following at the command line: + +
    +git clone https://android.googlesource.com/platform/frameworks/volley
    +
    +
  2. + +
  3. Import the downloaded source into your app project as an Android library project +(as described in +Managing Projects from Eclipse with ADT, if you're using Eclipse) or make a +.jar file.
  4. +
+ +

Lessons

+ +
+
+ Sending a Simple Request +
+
+ Learn how to send a simple request using the default behaviors of Volley, and how + to cancel a request. + +
+
+ Setting Up a RequestQueue +
+
+ Learn how to set up a {@code RequestQueue}, and how to implement a singleton + pattern to create a {@code RequestQueue} that lasts the lifetime of your app. +
+
+ Making a Standard Request +
+
+ Learn how to send a request using one of Volley's out-of-the-box request types + (raw strings, images, and JSON). +
+
+ Implementing a Custom Request +
+
+ Learn how to implement a custom request. +
+ +
diff --git a/docs/html/training/volley/request-custom.jd b/docs/html/training/volley/request-custom.jd new file mode 100644 index 0000000000000..7b669b9a9e9f7 --- /dev/null +++ b/docs/html/training/volley/request-custom.jd @@ -0,0 +1,163 @@ +page.title=Implementing a Custom Request + +trainingnavtop=true + +@jd:body + +
+
+ + +

This lesson teaches you to

+
    +
  1. Write a Custom Request
  2. +
+ +
+
+ + +
+

Video

+

Volley: Easy, Fast Networking for Android

+
+
+ +

This lesson describes how to implement your own custom request types, for types that +don't have out-of-the-box Volley support.

+ +

Write a Custom Request

+ +Most requests have ready-to-use implementations in the toolbox; if your response is a string, +image, or JSON, you probably won't need to implement a custom {@code Request}.

+ +

For cases where you do need to implement a custom request, this is all you need +to do:

+ +
    + +
  • Extend the {@code Request<T>} class, where +{@code <T>} represents the type of parsed response +the request expects. So if your parsed response is a string, for example, +create your custom request by extending {@code Request<String>}. See the Volley +toolbox classes {@code StringRequest} and {@code ImageRequest} for examples of +extending {@code Request<T>}.
  • + +
  • Implement the abstract methods {@code parseNetworkResponse()} +and {@code deliverResponse()}, described in more detail below.
  • + +
+ +

parseNetworkResponse

+ +

A {@code Response} encapsulates a parsed response for delivery, for a given type +(such as string, image, or JSON). Here is a sample implementation of +{@code parseNetworkResponse()}:

+ +
+@Override
+protected Response<T> parseNetworkResponse(
+        NetworkResponse response) {
+    try {
+        String json = new String(response.data,
+        HttpHeaderParser.parseCharset(response.headers));
+    return Response.success(gson.fromJson(json, clazz),
+    HttpHeaderParser.parseCacheHeaders(response));
+    }
+    // handle errors
+...
+}
+
+ +

Note the following:

+ +
    +
  • {@code parseNetworkResponse()} takes as its parameter a {@code NetworkResponse}, which +contains the response payload as a byte[], HTTP status code, and response headers.
  • +
  • Your implementation must return a {@code Response<T>}, which contains your typed +response object and cache metadata or an error, such as in the case of a parse failure.
  • +
+ +

If your protocol has non-standard cache semantics, you can build a {@code Cache.Entry} +yourself, but most requests are fine with something like this: +

+
return Response.success(myDecodedObject,
+        HttpHeaderParser.parseCacheHeaders(response));
+

+Volley calls {@code parseNetworkResponse()} from a worker thread. This ensures that +expensive parsing operations, such as decoding a JPEG into a Bitmap, don't block the UI +thread.

+ +

deliverResponse

+ +

Volley calls you back on the main thread with the object you returned in +{@code parseNetworkResponse()}. Most requests invoke a callback interface here, +for example: +

+ +
+protected void deliverResponse(T response) {
+        listener.onResponse(response);
+
+ +

Example: GsonRequest

+ +

Gson is a library for converting +Java objects to and from JSON using reflection. You can define Java objects that have the +same names as their corresponding JSON keys, pass Gson the class object, and Gson will fill +in the fields for you. Here's a complete implementation of a Volley request that uses +Gson for parsing:

+ +
+public class GsonRequest<T> extends Request<T> {
+    private final Gson gson = new Gson();
+    private final Class<T> clazz;
+    private final Map<String, String> headers;
+    private final Listener<T> listener;
+
+    /**
+     * Make a GET request and return a parsed object from JSON.
+     *
+     * @param url URL of the request to make
+     * @param clazz Relevant class object, for Gson's reflection
+     * @param headers Map of request headers
+     */
+    public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
+            Listener<T> listener, ErrorListener errorListener) {
+        super(Method.GET, url, errorListener);
+        this.clazz = clazz;
+        this.headers = headers;
+        this.listener = listener;
+    }
+
+    @Override
+    public Map<String, String> getHeaders() throws AuthFailureError {
+        return headers != null ? headers : super.getHeaders();
+    }
+
+    @Override
+    protected void deliverResponse(T response) {
+        listener.onResponse(response);
+    }
+
+    @Override
+    protected Response<T> parseNetworkResponse(NetworkResponse response) {
+        try {
+            String json = new String(
+                    response.data,
+                    HttpHeaderParser.parseCharset(response.headers));
+            return Response.success(
+                    gson.fromJson(json, clazz),
+                    HttpHeaderParser.parseCacheHeaders(response));
+        } catch (UnsupportedEncodingException e) {
+            return Response.error(new ParseError(e));
+        } catch (JsonSyntaxException e) {
+            return Response.error(new ParseError(e));
+        }
+    }
+}
+
+ +

Volley provides ready-to-use {@code JsonArrayRequest} and {@code JsonArrayObject} classes +if you prefer to take that approach. See +Using Standard Request Types for more information.

diff --git a/docs/html/training/volley/request.jd b/docs/html/training/volley/request.jd new file mode 100644 index 0000000000000..d8ccab2f07dcd --- /dev/null +++ b/docs/html/training/volley/request.jd @@ -0,0 +1,281 @@ +page.title=Making a Standard Request + +trainingnavtop=true + +@jd:body + +
+
+ + +

This lesson teaches you to

+
    +
  1. Request an Image
  2. +
  3. Request JSON
  4. +
+ +
+
+ + +
+

Video

+

Volley: Easy, Fast Networking for Android

+
+
+ +

+This lesson describes how to use the common request types that Volley supports:

+ +
    +
  • {@code StringRequest}. Specify a URL and receive a raw string in response. See + Setting Up a Request Queue for an example.
  • +
  • {@code ImageRequest}. Specify a URL and receive an image in response.
  • +
  • {@code JsonObjectRequest} and {@code JsonArrayRequest} (both subclasses of + {@code JsonRequest}). Specify a URL and get a JSON object or array (respectively) in + response.
  • +
+ +

If your expected response is one of these types, you probably won't have to implement a +custom request. This lesson describes how to use these standard request types. For +information on how to implement your own custom request, see +Implementing a Custom Request.

+ + +

Request an Image

+ +

Volley offers the following classes for requesting images. These classes layer on top +of each other to offer different levels of support for processing images:

+ +
    +
  • {@code ImageRequest}—a canned request for getting an image at a given URL and + calling back with a decoded bitmap. It also provides convenience features like specifying + a size to resize to. Its main benefit is that Volley's thread scheduling ensures that + expensive image operations (decoding, resizing) automatically happen on a worker thread.
  • + +
  • {@code ImageLoader}—a helper class that handles loading and caching images from + remote URLs. {@code ImageLoader} is a an orchestrator for large numbers of {@code ImageRequest}s, + for example when putting multiple thumbnails in a {@link android.widget.ListView}. + {@code ImageLoader} provides an in-memory cache to sit in front of the normal Volley + cache, which is important to prevent flickering. This makes it possible to achieve a + cache hit without blocking or deferring off the main thread, which is impossible when + using disk I/O. {@code ImageLoader} also does response coalescing, without which almost + every response handler would set a bitmap on a view and cause a layout pass per image. + Coalescing makes it possible to deliver multiple responses simultaneously, which improves + performance.
  • +
  • {@code NetworkImageView}—builds on {@code ImageLoader} and effectively replaces + {@link android.widget.ImageView} for situations where your image is being fetched over + the network via URL. {@code NetworkImageView} also manages canceling pending requests if + the view is detached from the hierarchy.
  • +
+ +

Use ImageRequest

+ +

Here is an example of using {@code ImageRequest}. It retrieves the image specified by +the URL and displays it in the app. Note that this snippet interacts with the +{@code RequestQueue} through a singleton class (see Setting Up a RequestQueue for more discussion of +this topic):

+ +
+ImageView mImageView;
+String url = "http://i.imgur.com/7spzG.png";
+mImageView = (ImageView) findViewById(R.id.myImage);
+...
+
+// Retrieves an image specified by the URL, displays it in the UI.
+ImageRequest request = new ImageRequest(url,
+    new Response.Listener() {
+        @Override
+        public void onResponse(Bitmap bitmap) {
+            mImageView.setImageBitmap(bitmap);
+        }
+    }, 0, 0, null,
+    new Response.ErrorListener() {
+        public void onErrorResponse(VolleyError error) {
+            mImageView.setImageResource(R.drawable.image_load_error);
+        }
+    });
+// Access the RequestQueue through your singleton class.
+MySingleton.getInstance(this).addToRequestQueue(request);
+ + +

Use ImageLoader and NetworkImageView

+ +

You can use {@code ImageLoader} and {@code NetworkImageView} in concert to efficiently +manage the display of multiple images, such as in a {@link android.widget.ListView}. In your +layout XML file, you use {@code NetworkImageView} in much the same way you would use +{@link android.widget.ImageView}, for example:

+ +
<com.android.volley.toolbox.NetworkImageView
+        android:id="@+id/networkImageView"
+        android:layout_width="150dp"
+        android:layout_height="170dp"
+        android:layout_centerHorizontal="true" />
+ +

You can use {@code ImageLoader} by itself to display an image, for example:

+ +
+ImageLoader mImageLoader;
+ImageView mImageView;
+// The URL for the image that is being loaded.
+private static final String IMAGE_URL =
+    "http://developer.android.com/images/training/system-ui.png";
+...
+mImageView = (ImageView) findViewById(R.id.regularImageView);
+
+// Get the ImageLoader through your singleton class.
+mImageLoader = MySingleton.getInstance(this).getImageLoader();
+mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
+         R.drawable.def_image, R.drawable.err_image));
+
+ +

However, {@code NetworkImageView} can do this for you if all you're doing is populating +an {@link android.widget.ImageView}. For example:

+ +
+ImageLoader mImageLoader;
+NetworkImageView mNetworkImageView;
+private static final String IMAGE_URL =
+    "http://developer.android.com/images/training/system-ui.png";
+...
+
+// Get the NetworkImageView that will display the image.
+mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
+
+// Get the ImageLoader through your singleton class.
+mImageLoader = MySingleton.getInstance(this).getImageLoader();
+
+// Set the URL of the image that should be loaded into this view, and
+// specify the ImageLoader that will be used to make the request.
+mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
+
+ +

The above snippets access the {@code RequestQueue} and the {@code ImageLoader} +through a singleton class, as described in +Setting Up a RequestQueue. This approach ensures that your app creates single instances of +these classes that last the lifetime of your app. The reason that this is important for +{@code ImageLoader} (the helper class that handles loading and caching images) is that +the main function of the in-memory cache is to allow for flickerless rotation. Using a +singleton pattern allows the bitmap cache to outlive the activity. If instead you create the +{@code ImageLoader} in an activity, the {@code ImageLoader} would be recreated along with +the activity every time the user rotates the device. This would cause flickering.

+ +

Example LRU cache

+ +

The Volley toolbox provides a standard cache implementation via the +{@code DiskBasedCache} class. This class caches files directly onto the hard disk in the +specified directory. But to use {@code ImageLoader}, you should provide a custom +in-memory LRU bitmap cache that implements the {@code ImageLoader.ImageCache} interface. +You may want to set up your cache as a singleton; for more discussion of this topic, see + +Setting Up a RequestQueue.

+ +

Here is a sample implementation for an in-memory {@code LruBitmapCache} class. +It extends the {@link android.support.v4.util.LruCache} class and implements the +{@code ImageLoader.ImageCache} interface:

+ +
+import android.graphics.Bitmap;
+import android.support.v4.util.LruCache;
+import android.util.DisplayMetrics;
+import com.android.volley.toolbox.ImageLoader.ImageCache;
+
+public class LruBitmapCache extends LruCache<String, Bitmap>
+        implements ImageCache {
+
+    public LruBitmapCache(int maxSize) {
+        super(maxSize);
+    }
+
+    public LruBitmapCache(Context ctx) {
+        this(getCacheSize(ctx));
+    }
+
+    @Override
+    protected int sizeOf(String key, Bitmap value) {
+        return value.getRowBytes() * value.getHeight();
+    }
+
+    @Override
+    public Bitmap getBitmap(String url) {
+        return get(url);
+    }
+
+    @Override
+    public void putBitmap(String url, Bitmap bitmap) {
+        put(url, bitmap);
+    }
+
+    // Returns a cache size equal to approximately three screens worth of images.
+    public static int getCacheSize(Context ctx) {
+        final DisplayMetrics displayMetrics = ctx.getResources().
+                getDisplayMetrics();
+        final int screenWidth = displayMetrics.widthPixels;
+        final int screenHeight = displayMetrics.heightPixels;
+        // 4 bytes per pixel
+        final int screenBytes = screenWidth * screenHeight * 4;
+
+        return screenBytes * 3;
+    }
+}
+
+ +

Here is an example of how to instantiate an {@code ImageLoader} to use this +cache:

+ +
+RequestQueue mRequestQueue; // assume this exists.
+ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
+            LruBitmapCache.getCacheSize()));
+
+ + +

Request JSON

+ +

Volley provides the following classes for JSON requests:

+ +
    +
  • {@code JsonArrayRequest}—A request for retrieving a + {@link org.json.JSONArray} + response body at a given URL.
  • +
  • {@code JsonObjectRequest}—A request for retrieving a + {@link org.json.JSONObject} + response body at a given URL, allowing for an optional + {@link org.json.JSONObject} + to be passed in as part of the request body.
  • +
+ +

Both classes are based on the common base class {@code JsonRequest}. You use them +following the same basic pattern you use for other types of requests. For example, this +snippet fetches a JSON feed and displays it as text in the UI:

+ +
+TextView mTxtDisplay;
+ImageView mImageView;
+mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
+String url = "http://my-json-feed";
+
+JsonObjectRequest jsObjRequest = new JsonObjectRequest
+        (Request.Method.GET, url, null, new Response.Listener() {
+
+    @Override
+    public void onResponse(JSONObject response) {
+        mTxtDisplay.setText("Response: " + response.toString());
+    }
+}, new Response.ErrorListener() {
+
+    @Override
+    public void onErrorResponse(VolleyError error) {
+        // TODO Auto-generated method stub
+
+    }
+});
+
+// Access the RequestQueue through your singleton class.
+MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
+
+ +For an example of implementing a custom JSON request based on +Gson, see the next lesson, +Implementing a Custom Request. diff --git a/docs/html/training/volley/requestqueue.jd b/docs/html/training/volley/requestqueue.jd new file mode 100644 index 0000000000000..6858d91e6eac6 --- /dev/null +++ b/docs/html/training/volley/requestqueue.jd @@ -0,0 +1,204 @@ +page.title=Setting Up a RequestQueue + +trainingnavtop=true + +@jd:body + +
+
+ + +

This lesson teaches you to

+
    +
  1. Set Up a Network and Cache
  2. +
  3. Use a Singleton Pattern
  4. +
+ +
+
+ + +
+

Video

+

Volley: Easy, Fast Networking for Android

+
+
+ + +

The previous lesson showed you how to use the convenience method +Volley.newRequestQueue to set up a {@code RequestQueue}, taking advantage of +Volley's default behaviors. This lesson walks you through the explicit steps of creating a +{@code RequestQueue}, to allow you to supply your own custom behavior.

+ +

This lesson also describes the recommended practice of creating a {@code RequestQueue} +as a singleton, which makes the {@code RequestQueue} last the lifetime of your app.

+ +

Set Up a Network and Cache

+ +

A {@code RequestQueue} needs two things to do its job: a network to perform transport +of the requests, and a cache to handle caching. There are standard implementations of these +available in the Volley toolbox: {@code DiskBasedCache} provides a one-file-per-response +cache with an in-memory index, and {@code BasicNetwork} provides a network transport based +on your choice of {@link android.net.http.AndroidHttpClient} or {@link java.net.HttpURLConnection}.

+ +

{@code BasicNetwork} is Volley's default network implementation. A {@code BasicNetwork} +must be initialized with the HTTP client your app is using to connect to the network. +Typically this is {@link android.net.http.AndroidHttpClient} or +{@link java.net.HttpURLConnection}:

+
    +
  • Use {@link android.net.http.AndroidHttpClient} for apps targeting Android API levels +lower than API Level 9 (Gingerbread). Prior to Gingerbread, {@link java.net.HttpURLConnection} +was unreliable. For more discussion of this topic, see + +Android's HTTP Clients.
  • + +
  • Use {@link java.net.HttpURLConnection} for apps targeting Android API Level 9 +(Gingerbread) and higher.
  • +
+

To create an app that runs on all versions of Android, you can check the version of +Android the device is running and choose the appropriate HTTP client, for example:

+ +
+HttpStack stack;
+...
+// If the device is running a version >= Gingerbread...
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
+    // ...use HttpURLConnection for stack.
+} else {
+    // ...use AndroidHttpClient for stack.
+}
+Network network = new BasicNetwork(stack);
+
+ +

This snippet shows you the steps involved in setting up a +{@code RequestQueue}:

+ +
+RequestQueue mRequestQueue;
+
+// Instantiate the cache
+Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
+
+// Set up the network to use HttpURLConnection as the HTTP client.
+Network network = new BasicNetwork(new HurlStack());
+
+// Instantiate the RequestQueue with the cache and network.
+mRequestQueue = new RequestQueue(cache, network);
+
+// Start the queue
+mRequestQueue.start();
+
+String url ="http://www.myurl.com";
+
+// Formulate the request and handle the response.
+StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
+        new Response.Listener<String>() {
+    @Override
+    public void onResponse(String response) {
+        // Do something with the response
+    }
+},
+    new Response.ErrorListener() {
+        @Override
+        public void onErrorResponse(VolleyError error) {
+            // Handle error
+    }
+});
+
+// Add the request to the RequestQueue.
+mRequestQueue.add(stringRequest);
+...
+
+ +

If you just need to make a one-time request and don't want to leave the thread pool +around, you can create the {@code RequestQueue} wherever you need it and call {@code stop()} on the +{@code RequestQueue} once your response or error has come back, using the +{@code Volley.newRequestQueue()} method described in Sending a Simple +Request. But the more common use case is to create the {@code RequestQueue} as a +singleton to keep it running for the lifetime of your app, as described in the next section.

+ + +

Use a Singleton Pattern

+ +

If your application makes constant use of the network, it's probably most efficient to +set up a single instance of {@code RequestQueue} that will last the lifetime of your app. +You can achieve this in various ways. The recommended approach is to implement a singleton +class that encapsulates {@code RequestQueue} and other Volley +functionality. Another approach is to subclass {@link android.app.Application} and set up the +{@code RequestQueue} in {@link android.app.Application#onCreate Application.onCreate()}. +But this approach is +discouraged; a static singleton can provide the same functionality in a more modular +way.

+ +

A key concept is that the {@code RequestQueue} must be instantiated with the +{@link android.app.Application} context, not an {@link android.app.Activity} context. This +ensures that the {@code RequestQueue} will last for the lifetime of your app, instead of +being recreated every time the activity is recreated (for example, when the user +rotates the device). + +

Here is an example of a singleton class that provides {@code RequestQueue} and +{@code ImageLoader} functionality:

+ +
private static MySingleton mInstance;
+    private RequestQueue mRequestQueue;
+    private ImageLoader mImageLoader;
+    private static Context mCtx;
+
+    private MySingleton(Context context) {
+        mCtx = context;
+        mRequestQueue = getRequestQueue();
+
+        mImageLoader = new ImageLoader(mRequestQueue,
+                new ImageLoader.ImageCache() {
+            private final LruCache<String, Bitmap>
+                    cache = new LruCache<String, Bitmap>(20);
+
+            @Override
+            public Bitmap getBitmap(String url) {
+                return cache.get(url);
+            }
+
+            @Override
+            public void putBitmap(String url, Bitmap bitmap) {
+                cache.put(url, bitmap);
+            }
+        });
+    }
+
+    public static synchronized MySingleton getInstance(Context context) {
+        if (mInstance == null) {
+            mInstance = new MySingleton(context);
+        }
+        return mInstance;
+    }
+
+    public RequestQueue getRequestQueue() {
+        if (mRequestQueue == null) {
+            // getApplicationContext() is key, it keeps you from leaking the
+            // Activity or BroadcastReceiver if someone passes one in.
+            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
+        }
+        return mRequestQueue;
+    }
+
+    public <T> void addToRequestQueue(Request<T> req) {
+        getRequestQueue().add(req);
+    }
+
+    public ImageLoader getImageLoader() {
+        return mImageLoader;
+    }
+}
+ +

Here are some examples of performing {@code RequestQueue} operations using the singleton +class:

+ +
+// Get a RequestQueue
+RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
+    getRequestQueue();
+...
+
+// Add a request (in this example, called stringRequest) to your RequestQueue.
+MySingleton.getInstance(this).addToRequestQueue(stringRequest);
+
diff --git a/docs/html/training/volley/simple.jd b/docs/html/training/volley/simple.jd new file mode 100644 index 0000000000000..942c57f0af75a --- /dev/null +++ b/docs/html/training/volley/simple.jd @@ -0,0 +1,169 @@ +page.title=Sending a Simple Request + +trainingnavtop=true + +@jd:body + +
+
+ + +

This lesson teaches you to

+
    +
  1. Add the INTERNET Permission
  2. +
  3. Use newRequestQueue
  4. +
  5. Send a Request
  6. +
  7. Cancel a Request
  8. +
+ +
+
+ + +
+

Video

+

Volley: Easy, Fast Networking for Android

+
+
+ +

At a high level, you use Volley by creating a {@code RequestQueue} and passing it +{@code Request} objects. The {@code RequestQueue} manages worker threads for running the +network operations, reading from and writing to the cache, and parsing responses. Requests +do the parsing of raw responses and Volley takes care of dispatching the parsed response +back to the main thread for delivery.

+ +

This lesson describes how to send a request using the Volley.newRequestQueue +convenience method, which sets up a {@code RequestQueue} for you. +See the next lesson, +Setting Up a RequestQueue, for information on how to set +up a {@code RequestQueue} yourself.

+ +

This lesson also describes how to add a request to a {@code RequestQueue} and cancel a +request.

+ +

Add the INTERNET Permission

+ +

To use Volley, you must add the +{@link android.Manifest.permission#INTERNET android.permission.INTERNET} permission +to your app's manifest. Without this, your app won't be able to connect to the network.

+ + +

Use newRequestQueue

+ +

Volley provides a convenience method Volley.newRequestQueue that sets up a +{@code RequestQueue} for you, using default values, and starts the queue. For example:

+ +
+final TextView mTextView = (TextView) findViewById(R.id.text);
+...
+
+// Instantiate the RequestQueue.
+RequestQueue queue = Volley.newRequestQueue(this);
+String url ="http://www.google.com";
+
+// Request a string response from the provided URL.
+StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
+            new Response.Listener() {
+    @Override
+    public void onResponse(String response) {
+        // Display the first 500 characters of the response string.
+        mTextView.setText("Response is: "+ response.substring(0,500));
+    }
+}, new Response.ErrorListener() {
+    @Override
+    public void onErrorResponse(VolleyError error) {
+        mTextView.setText("That didn't work!");
+    }
+});
+// Add the request to the RequestQueue.
+queue.add(stringRequest);
+
+ +

Volley always delivers parsed responses on the main thread. Running on the main thread +is convenient for populating UI controls with received data, as you can freely modify UI +controls directly from your response handler, but it's especially critical to many of the +important semantics provided by the library, particularly related to canceling requests. +

+ +

See Setting Up a RequestQueue for a +description of how to set up a {@code RequestQueue} yourself, instead of using the +Volley.newRequestQueue convenience method.

+ +

Send a Request

+ +

To send a request, you simply construct one and add it to the {@code RequestQueue} with +{@code add()}, as shown above. Once you add the request it moves through the pipeline, +gets serviced, and has its raw response parsed and delivered.

+ +

When you call {@code add()}, Volley runs one cache processing thread and a pool of +network dispatch threads. When you add a request to the queue, it is picked up by the cache +thread and triaged: if the request can be serviced from cache, the cached response is +parsed on the cache thread and the parsed response is delivered on the main thread. If the +request cannot be serviced from cache, it is placed on the network queue. The first +available network thread takes the request from the queue, performs the HTTP transaction, +parsse the response on the worker thread, writes the response to cache, and posts the parsed +response back to the main thread for delivery.

+ +

Note that expensive operations like blocking I/O and parsing/decoding are done on worker +threads. You can add a request from any thread, but responses are always delivered on the +main thread.

+ +

Figure 1 illustrates the life of a request:

+ + system bars +

Figure 1. Life of a request.

+ + +

Cancel a Request

+ +

To cancel a request, call {@code cancel()} on your {@code Request} object. Once cancelled, +Volley guarantees that your response handler will never be called. What this means in +practice is that you can cancel all of your pending requests in your activity's +{@link android.app.Activity#onStop onStop()} method and you don't have to litter your +response handlers with checks for {@code getActivity() == null}, +whether {@code onSaveInstanceState()} has been called already, or other defensive +boilerplate.

+ +

To take advantage of this behavior, you would typically have to +track all in-flight requests in order to be able to cancel them at the +appropriate time. There is an easier way: you can associate a tag object with each +request. You can then use this tag to provide a scope of requests to cancel. For +example, you can tag all of your requests with the {@link android.app.Activity} they +are being made on behalf of, and call {@code requestQueue.cancelAll(this)} from +{@link android.app.Activity#onStop onStop()}. +Similarly, you could tag all thumbnail image requests in a +{@link android.support.v4.view.ViewPager} tab with their respective tabs and cancel on swipe +to make sure that the new tab isn't being held up by requests from another one.

+ +

Here is an example that uses a string value for the tag:

+ +
    +
  1. Define your tag and add it to your requests. +
    +public static final String TAG = "MyTag";
    +StringRequest stringRequest; // Assume this exists.
    +RequestQueue mRequestQueue;  // Assume this exists.
    +
    +// Set the tag on the request.
    +stringRequest.setTag(TAG);
    +
    +// Add the request to the RequestQueue.
    +mRequestQueue.add(stringRequest);
    +
  2. + +
  3. In your activity's {@link android.app.Activity#onStop onStop()} method, cancel all requests that have this tag. +
    +@Override
    +protected void onStop () {
    +    super.onStop();
    +    if (mRequestQueue != null) {
    +        mRequestQueue.cancelAll(TAG);
    +    }
    +}
    +
+ +

Take care when canceling requests. If you are depending on your response handler to +advance a state or kick off another process, you need to account for this. Again, the +response handler will not be called. +

diff --git a/docs/image_sources/training/volley/volley-request.graffle b/docs/image_sources/training/volley/volley-request.graffle new file mode 100644 index 0000000000000..1d79b3dff9bf8 --- /dev/null +++ b/docs/image_sources/training/volley/volley-request.graffle @@ -0,0 +1,2259 @@ + + + + + ActiveLayerIndex + 0 + ApplicationVersion + + com.omnigroup.OmniGrafflePro + 139.18.0.187838 + + AutoAdjust + + BackgroundGraphic + + Bounds + {{0, 0}, {576, 733}} + Class + SolidGraphic + ID + 2 + Style + + shadow + + Draws + NO + + stroke + + Draws + NO + + + + BaseZoom + 0 + CanvasOrigin + {0, 0} + ColumnAlign + 1 + ColumnSpacing + 36 + CreationDate + 2014-03-24 22:38:51 +0000 + Creator + Katie McCormick + DisplayScale + 1 0/72 in = 1 0/72 in + GraphDocumentVersion + 8 + GraphicsList + + + Bounds + {{68.798424333456921, 309.90064645900816}, {70.999998092651367, 24}} + Class + ShapedGraphic + FitText + Vertical + Flow + Resize + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Helvetica + Size + 12 + + ID + 1990 + Rotation + 88.863800048828125 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\fs24 \cf0 cache miss} + + + + Bounds + {{164.31081962585449, 233}, {59, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Helvetica + Size + 12 + + ID + 1989 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\fs24 \cf0 cache hit} + + Wrap + NO + + + Bounds + {{109, 567.5}, {72, 24}} + Class + ShapedGraphic + FitText + YES + Flow + Resize + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Helvetica + Size + 12 + + ID + 1987 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Align + 0 + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720 + +\f0\fs24 \cf0 round-robin} + + Wrap + NO + + + Class + LineGraphic + Head + + ID + 209 + + ID + 1986 + Points + + {362.483096786499, 520.41741752624512} + {439.59458923339844, 165.16970062255859} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 213 + Info + 7 + + + + Class + LineGraphic + Head + + ID + 209 + + ID + 1985 + Points + + {362.483096786499, 461.33483529090881} + {439.59458923339844, 165.16970062255859} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 204 + Info + 7 + + + + Class + LineGraphic + Head + + ID + 209 + + ID + 1984 + Points + + {362.48308152770994, 402.2522608306885} + {439.59458923339844, 165.16970062255859} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 203 + Info + 7 + + + + Class + LineGraphic + Head + + ID + 209 + + ID + 1983 + Points + + {294.65540856933592, 227.99996948242188} + {381.3049268594778, 164.77353614247437} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 210 + Info + 6 + + + + Class + LineGraphic + Head + + ID + 4 + Info + 6 + + ID + 1982 + Points + + {94.216227905273399, 165.16970062255859} + {92.966230102539043, 227.99999237060547} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 157 + Info + 5 + + + + Class + LineGraphic + Head + + ID + 213 + Info + 9 + + ID + 1980 + Points + + {179.26087951660151, 462.43391850741568} + {224.48312730407713, 514.92974541704564} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 1973 + Info + 3 + + + + Class + LineGraphic + Head + + ID + 204 + Info + 8 + + ID + 1979 + Points + + {179.76073189455099, 462.42177007636207} + {224.48312730407716, 461.33483529090881} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 1973 + + + + Class + LineGraphic + Head + + ID + 203 + Info + 8 + + ID + 1978 + Points + + {179.26087951660151, 462.43391850741568} + {224.48311204528804, 402.2522608306885} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 1973 + Info + 3 + + + + Class + LineGraphic + Head + + ID + 1973 + + ID + 1975 + Points + + {92.966230102539043, 286.16969299316406} + {92.966239929199205, 356.41910654608148} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 4 + Info + 5 + + + + Class + LineGraphic + Head + + ID + 210 + Info + 8 + + ID + 1974 + Points + + {150.81081933593748, 257.08484268188477} + {236.81081933593748, 257.08481979370117} + + Style + + stroke + + HeadArrow + FilledArrow + Legacy + + TailArrow + 0 + + + Tail + + ID + 4 + Info + 7 + + + + Bounds + {{391, 540.66744232177734}, {137.99996948242188, 23.499996185302734}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 214 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 network threads} + VerticalPad + 0 + + + + Bounds + {{224.48312730407713, 508.66741943359375}, {137.99996948242188, 23.499996185302734}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 213 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 HTTP...} + VerticalPad + 0 + + + + Bounds + {{23.966230102539043, 498}, {137.99998474121094, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 212 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request dequeued by NetworkDispatcher} + VerticalPad + 0 + + + + Bounds + {{23.966245361328106, 432.24999237060547}, {137.99998474121094, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 211 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request dequeued by NetworkDispatcher} + VerticalPad + 0 + + + + Bounds + {{236.81081933593748, 227.99996948242188}, {115.68917846679688, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 10 + + ID + 210 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.8 + r + 0.6 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0 + g + 0.6 + r + 0.4 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request read from cache and parsed} + VerticalPad + 0 + + + + Bounds + {{380.5, 107}, {118.18917846679688, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 209 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.898039 + g + 0.709804 + r + 0.2 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.93512 + g + 0.472602 + r + 0.333854 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Parsed response delivered on main thread} + VerticalPad + 0 + + + + Bounds + {{391, 508.66740417480469}, {137.99996948242188, 23.499996185302734}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 10 + + ID + 207 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.8 + r + 0.6 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0 + g + 0.6 + r + 0.4 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 cache thread} + VerticalPad + 0 + + + + Bounds + {{391, 476.6673583984375}, {137.99996948242188, 23.499980926513672}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 206 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.898039 + g + 0.709804 + r + 0.2 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.93512 + g + 0.472602 + r + 0.333854 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 main thread} + VerticalPad + 0 + + + + Bounds + {{224.48312730407713, 421.74998497962952}, {137.99996948242188, 79.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 204 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 HTTP transaction, response parse, cache write (if applicable)} + VerticalPad + 0 + + + + Bounds + {{224.48311204528807, 390.50226273803713}, {137.99996948242188, 23.499996185302734}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 203 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 HTTP...} + VerticalPad + 0 + + + + Bounds + {{23.966245361328106, 366.5}, {137.99998474121094, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 200 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.2 + g + 0.733333 + r + 1 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.131021 + g + 0.363196 + r + 0.725948 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request dequeued by NetworkDispatcher} + VerticalPad + 0 + + + + Bounds + {{35.121640869140606, 227.99999237060547}, {115.68917846679688, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 10 + + ID + 4 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0 + g + 0.8 + r + 0.6 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0 + g + 0.6 + r + 0.4 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request dequeued by CacheDispatcher} + VerticalPad + 0 + + + + Bounds + {{35.121638671874962, 107}, {118.18917846679688, 58.169700622558594}} + Class + ShapedGraphic + FontInfo + + Color + + b + 0 + g + 0 + r + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 157 + Magnets + + {1, 1} + {1, -1} + {-1, -1} + {-1, 1} + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + {-0.5, -0.233518} + {-0.49144199999999999, 0.26006299999999999} + {0.50711799999999996, -0.22408600000000001} + {0.50711799999999996, 0.267179} + {-0.27431, -0.474028} + {0.27977999999999997, -0.47847800000000001} + {0.29393799999999998, 0.54304399999999997} + {-0.28623199999999999, 0.55380399999999996} + + Shape + Rectangle + Style + + fill + + Color + + b + 0.898039 + g + 0.709804 + r + 0.2 + + + shadow + + Color + + a + 0.35 + b + 0.328823 + g + 0.328823 + r + 0.328823 + + Fuzziness + 1.5349206924438477 + ShadowVector + {0, 1} + + stroke + + Color + + b + 0.93512 + g + 0.472602 + r + 0.333854 + + CornerRadius + 2 + Draws + NO + + + Text + + Text + {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf190 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc + +\f0\b\fs24 \cf0 Request added to queue in priority order} + VerticalPad + 0 + + + + Class + Group + Graphics + + + Bounds + {{20.00199264625337, 331.00000000000006}, {145.92853034472586, 25.419100784950434}} + Class + ShapedGraphic + FontInfo + + Color + + a + 0.65 + b + 0 + g + 0 + r + 0 + + Font + Roboto-Condensed + Size + 12 + + ID + 1972 + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Draws + NO + + + Text + + Pad + 2 + + + + Bounds + {{6.671600341796875, 356.41910654608148}, {172.58927917480466, 212.02962392266838}} + Class + ShapedGraphic + FontInfo + + Color + + a + 0.65 + w + 0 + + Font + Roboto-BoldCondensed + Size + 12 + + ID + 1973 + Magnets + + {0, 1} + {0, -1} + {1, 0} + {-1, 0} + + Shape + Rectangle + Style + + fill + + Draws + NO + + shadow + + Draws + NO + + stroke + + Color + + b + 0.578326 + g + 0.578615 + r + 0.578453 + + CornerRadius + 5 + Pattern + 1 + + + Text + + VerticalPad + 10 + + TextPlacement + 0 + + + ID + 1971 + + + GridInfo + + GuidesLocked + NO + GuidesVisible + YES + HPages + 1 + ImageCounter + 1 + KeepToScale + + Layers + + + Lock + NO + Name + Layer 1 + Print + YES + View + YES + + + LayoutInfo + + Animate + NO + circoMinDist + 18 + circoSeparation + 0.0 + layoutEngine + dot + neatoSeparation + 0.0 + twopiSeparation + 0.0 + + LinksVisible + NO + MagnetsVisible + NO + MasterSheets + + ModificationDate + 2014-03-24 23:38:43 +0000 + Modifier + Katie McCormick + NotesVisible + NO + Orientation + 2 + OriginVisible + NO + PageBreaks + YES + PrintInfo + + NSBottomMargin + + float + 41 + + NSHorizonalPagination + + coded + BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG + + NSLeftMargin + + float + 18 + + NSPaperSize + + size + {612, 792} + + NSPrintReverseOrientation + + int + 0 + + NSRightMargin + + float + 18 + + NSTopMargin + + float + 18 + + + PrintOnePage + + ReadOnly + NO + RowAlign + 1 + RowSpacing + 36 + SheetTitle + Canvas 1 + SmartAlignmentGuidesActive + YES + SmartDistanceGuidesActive + YES + UniqueID + 1 + UseEntirePage + + VPages + 1 + WindowInfo + + CurrentSheet + 0 + ExpandedCanvases + + + name + Canvas 1 + + + Frame + {{159, 135}, {899, 874}} + ListView + + OutlineWidth + 142 + RightSidebar + + ShowRuler + + Sidebar + + SidebarWidth + 120 + VisibleRegion + {{-94, -1}, {764, 735}} + Zoom + 1 + ZoomValues + + + Canvas 1 + 1 + 1 + + + + +