Download - 110 volley easy, fast networking for android
![Page 1: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/1.jpg)
VolleyEasy, Fast Networking for Android
Ficus KirkpatrickGoogle, Inc.
![Page 2: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/2.jpg)
What is Volley?
volley (\ˈvä-lē\) n.:
the flight of the ball (as in volleyball or tennis) or its course before striking the ground
![Page 3: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/3.jpg)
What is Volley?
volley (\ˈvä-lē\), n.:
a burst or emission of many things or a large amount at once
![Page 4: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/4.jpg)
Everything you need
JSON, images, raw text
Memory and disk caching
Powerful customization abilities
Debugging and tracing tools
![Page 5: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/5.jpg)
But why?Android already has HTTP client support, right?
![Page 6: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/6.jpg)
What do these all have in common?
![Page 7: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/7.jpg)
Design tradeoffs
Great for RPC-style network operations that populate UI
Fine for background RPCs
Terrible for large payloads
![Page 8: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/8.jpg)
A simple appPaginated list of strings with thumbnail images
![Page 9: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/9.jpg)
Simple JSON protocol
GET /api/list HTTP/1.1
{"items": [ { "title": "Dollar Bill", "description": "Please. Mr. Y'all was my father.", "image_url": "/static/24.jpg" }, { "title": "Tennis Ball", "description": "Every dog's favorite.", "image_url": "/static/60.jpg" }, ...
], "next": "10_10" }
![Page 10: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/10.jpg)
Simple JSON protocol
GET /api/list HTTP/1.1
{"items": [ { "title": "Dollar Bill", "description": "Please. Mr. Y'all was my father.", "image_url": "/static/24.jpg" }, { "title": "Tennis Ball", "description": "Every dog's favorite.", "image_url": "/static/60.jpg" }, ...
], "next": "10_10" }
![Page 11: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/11.jpg)
Simple JSON protocol
GET /api/list HTTP/1.1GET /api/list HTTP/1.1
{"items": [ { "title": "Dollar Bill", "description": "Please. Mr. Y'all was my father.", "image_url": "/static/24.jpg" }, { "title": "Tennis Ball", "description": "Every dog's favorite.", "image_url": "/static/60.jpg" }, ...
], "next": "10_10" }
![Page 12: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/12.jpg)
Application architecture
Activity
ListView
Adapter API Server
![Page 13: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/13.jpg)
Typical implementation
Adapter loads data from getView()
Java@Overridepublic View getView(int position, View view, ViewGroup parent) {
// Load more if we're close to the end.if (closeToEnd(position) && !mLoading) {
loadMoreData();}
// Make the views...
![Page 14: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/14.jpg)
Typical implementation
loadMoreData()
Java
// private class LoadItemsTask extends AsyncTask<URL, Void, JSONObject> {
protected JSONObject doInBackground(URL... params) {HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();InputStream input = conn.getInputStream();ByteArrayOutputStream baos = new ByteArrayOutputStream();copy(input, baos);JSONObject jsonRoot = new JSONObject(baos.toString());return jsonRoot;
}
![Page 15: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/15.jpg)
Typical implementation
loadMoreData()
Java
// private class LoadItemsTask extends AsyncTask<URL, Void, JSONObject> {
protected void onPostExecute(JSONObject jsonRoot) {List<Items> items = parseJson(jsonRoot);appendItemsToList(item);notifyDataSetChanged();
}
![Page 16: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/16.jpg)
Typical implementation
Back in getView()
Java
@Overridepublic View getView(int position, View view, ViewGroup parent) {
// Load more if needed, make ViewHolder, etc.
mTitleView.setText(item.title);
mDescriptionView.setText(item.description);
new LoadImageTask(holder.imageView).execute(
new URL(BASE_URL + item.imageUrl));
![Page 17: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/17.jpg)
Typical implementation
LoadImageTask
Java
// private class LoadImageTask extends AsyncTask<URL, Void, Bitmap> {
public LoadImageTask(ImageView imageView) {mImageView = imageView;
}
protected Bitmap doInBackground(URL... params) {HttpURLConnection conn = (HttpURLConnection) params[0].openConnection();InputStream input = conn.getInputStream();return BitmapFactory.decodeStream(input);
}
![Page 18: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/18.jpg)
Typical implementation
LoadImageTask
Java
// private class LoadImageTask extends AsyncTask<URL, Void, Bitmap> {
protected void onPostExecute(Bitmap result) {mImageView.setImageBitmap(result);
}
![Page 19: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/19.jpg)
Problems and solutionsTypical approach vs. Volley approach
![Page 20: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/20.jpg)
Problems
All network requests happen serially
![Page 21: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/21.jpg)
Problems
Rotating the screen will reload everything from the network
![Page 22: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/22.jpg)
Problems
AsyncTasks stomp on recycled views
![Page 23: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/23.jpg)
Problems
Compatibility problems on Froyo
![Page 24: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/24.jpg)
Volley implementation
Setup
Java// Somewhere common; app startup or adapter constructor
mRequestQueue = Volley.newRequestQueue(context);mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
![Page 25: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/25.jpg)
Volley implementation
loadMoreData()
Java
mRequestQueue.add(new JsonObjectRequest(Method.GET, url, null,new Listener<JSONObject>() {
public void onResponse(JSONObject jsonRoot) {mNextPageToken = jsonGet(jsonRoot, "next", null);List<Items> items = parseJson(jsonRoot);appendItemsToList(item);notifyDataSetChanged();
}}
}
![Page 26: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/26.jpg)
Volley implementation
Retrieving images with ImageLoader
Javaif (holder.imageRequest != null) {
holder.imageRequest.cancel();}
holder.imageRequest = mImageLoader.get(BASE_URL + item.image_url,holder.imageView, R.drawable.loading, R.drawable.error);
![Page 27: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/27.jpg)
Volley implementation
Using NetworkImageView
- <ImageView
+ <com.android.volley.NetworkImageView
JavamImageView.setImageUrl(BASE_URL + item.image_url, mImageLoader);
XML
![Page 28: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/28.jpg)
Easy to write custom requests
Java @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)); } }
https://gist.github.com/ficusk/5474673
![Page 29: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/29.jpg)
Gson implementation
loadMoreData()
Java
mRequestQueue.add(new GsonRequest<ListResponse>(url, ListResponse.class, null,new Listener<ListResponse>() {
public void onResponse(ListResponse response) {appendItemsToList(response.items);
notifyDataSetChanged();
}
}
}
![Page 30: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/30.jpg)
Under the hoodArchitecture and semantics
![Page 31: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/31.jpg)
Request added to cache queue in priority order
Request dequeued by
CacheDispatcher
Parsed response delivered on main
thread
Response read from cache and parsed
Request dequeued by NetworkDispatcher
...
...
miss
hit
main thread
cache thread
network threadsround-robin
HTTP transaction, response parsed, cache write
...
...
![Page 32: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/32.jpg)
Debugging and tracing
adb shell setprop log.tag.Volley VERBOSE
D/Volley ( 6027): [1] MarkerLog.finish: (443 ms) [ ] http://ficus.me:8080/static/05.jpg LOW 11
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
D/Volley ( 6027): [1] MarkerLog.finish: (+68 ) [15] cache-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [15] cache-hit-expired
D/Volley ( 6027): [1] MarkerLog.finish: (+136 ) [19] network-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+127 ) [19] network-http-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+101 ) [19] network-parse-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+9 ) [19] network-cache-written
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [19] post-response
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [ 1] done
![Page 33: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/33.jpg)
Debugging and tracing
adb shell setprop log.tag.Volley VERBOSE
D/Volley ( 6027): [1] MarkerLog.finish: (443 ms) [ ] http://ficus.me:8080/static/05.jpg LOW 11
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
D/Volley ( 6027): [1] MarkerLog.finish: (+68 ) [15] cache-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [15] cache-hit-expired
D/Volley ( 6027): [1] MarkerLog.finish: (+136 ) [19] network-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+127 ) [19] network-http-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+101 ) [19] network-parse-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+9 ) [19] network-cache-written
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [19] post-response
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [ 1] done
![Page 34: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/34.jpg)
Debugging and tracing
adb shell setprop log.tag.Volley VERBOSE
D/Volley ( 6027): [1] MarkerLog.finish: (443 ms) [ ] http://ficus.me:8080/static/05.jpg LOW 11
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
D/Volley ( 6027): [1] MarkerLog.finish: (+68 ) [15] cache-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [15] cache-hit-expired
D/Volley ( 6027): [1] MarkerLog.finish: (+136 ) [19] network-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+127 ) [19] network-http-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+101 ) [19] network-parse-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+9 ) [19] network-cache-written
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [19] post-response
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [ 1] done
![Page 35: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/35.jpg)
Debugging and tracing
adb shell setprop log.tag.Volley VERBOSE
D/Volley ( 6027): [1] MarkerLog.finish: (443 ms) [ ] http://ficus.me:8080/static/05.jpg LOW 11
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
D/Volley ( 6027): [1] MarkerLog.finish: (+68 ) [15] cache-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [15] cache-hit-expired
D/Volley ( 6027): [1] MarkerLog.finish: (+136 ) [19] network-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+127 ) [19] network-http-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+101 ) [19] network-parse-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+9 ) [19] network-cache-written
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [19] post-response
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [ 1] done
![Page 36: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/36.jpg)
Debugging and tracing
adb shell setprop log.tag.Volley VERBOSE
D/Volley ( 6027): [1] MarkerLog.finish: (443 ms) [ ] http://ficus.me:8080/static/05.jpg LOW 11
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
D/Volley ( 6027): [1] MarkerLog.finish: (+68 ) [15] cache-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [15] cache-hit-expired
D/Volley ( 6027): [1] MarkerLog.finish: (+136 ) [19] network-queue-take
D/Volley ( 6027): [1] MarkerLog.finish: (+127 ) [19] network-http-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+101 ) [19] network-parse-complete
D/Volley ( 6027): [1] MarkerLog.finish: (+9 ) [19] network-cache-written
D/Volley ( 6027): [1] MarkerLog.finish: (+0 ) [19] post-response
D/Volley ( 6027): [1] MarkerLog.finish: (+1 ) [ 1] done
![Page 37: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/37.jpg)
The main threadOr, how I learned to stop using synchronized
![Page 38: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/38.jpg)
The main thread
Ever written this block of code?
Java@Overridepublic void onPostExecute(Result r) { if (getActivity() == null) { return; }
// ...
![Page 39: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/39.jpg)
The main thread
Java
@Overridepublic void onStop() { for (Request <?> req : mInFlightRequests) { req.cancel();
}
...
All responses are delivered to the main thread
If you cancel from the main thread, Volley guarantees your response will not be delivered
![Page 40: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/40.jpg)
The main thread
Java
@Overridepublic void onStop() { mRequestQueue.cancelAll(this);
...
All responses are delivered to the main thread
If you cancel from the main thread, Volley guarantees your response will not be delivered
![Page 41: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/41.jpg)
The main thread
Java
@Overridepublic void onStop() { mRequestQueue.cancelAll(
new RequestFilter() { ...
All responses are delivered to the main thread
If you cancel from the main thread, Volley guarantees your response will not be delivered
![Page 42: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/42.jpg)
Wrapping upWhat does it all mean?
![Page 43: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/43.jpg)
How to get started
1. Clone the Volley project
2. Import the code into your project
3. Volley.newRequestQueue(context)
git clone https://android.googlesource.com/platform/frameworks/volley
![Page 44: 110 volley easy, fast networking for android](https://reader030.vdocument.in/reader030/viewer/2022020400/568c56321a28ab4916c5a761/html5/thumbnails/44.jpg)
Thanks!
http://google.com/+FicusKirkpatrickhttp://twitter.com/ficushttps://groups.google.com/forum/?fromgroups#!forum/volley-users