<uses-permission android:name="android.permission.INTERNET" />
RequestQueue mQueue = Volley.newRequestQueue(context);
/** method:请求方法
url:请求的地址
listener:响应成功的监听器
errorListener:出错时的监听器 **/
public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener)
/**不传入method,默认会调用GET方式进行请求**/
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
StringRequest stringRequest = new StringRequest("http://www.baidu.com",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
showlog(error.getMessage());
}
});
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
mQueue.add(stringRequest);
//jsonRequest:POST请求携带的参数,可以为空,表示不携带参数
public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, errorListener);
}
//如果jsonRequest为空,默认使用GET请求,否则使用POST
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener) {
this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest, listener, errorListener);
}
RequestQueue mQueue = Volley.newRequestQueue(context);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://weather.51wnl.com/weatherinfo/GetMoreWeather?cityCode=101020100&weatherType=0", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_SHORT).show();
try {
response = response.getJSONObject("weatherinfo");
showlog("city = " + response.getString("city"));
showlog("weather1 = " + response.getString("weather1"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
showlog(error.getMessage());
}
});
mQueue.add(jsonObjectRequest);
Map<String, String> params = new HashMap<String, String>();
params.put("name1", "value1");
params.put("name2", "value2");
JSONObject jsonRequest= new JSONObject(params);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, url, jsonRequest, listener, errorListener)
public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, Config decodeConfig, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
setRetryPolicy(new DefaultRetryPolicy(IMAGE_TIMEOUT_MS, IMAGE_MAX_RETRIES, IMAGE_BACKOFF_MULT));
mListener = listener;
mDecodeConfig = decodeConfig;
mMaxWidth = maxWidth;
mMaxHeight = maxHeight;
}
RequestQueue mQueue = Volley.newRequestQueue(context);
ImageRequest imageRequest = new ImageRequest(
"http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
image.setImageBitmap(response);
}
}, 0, 0, Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
image.setImageResource(R.drawable.default_image);
}
});
mQueue.add(imageRequest);
ImageLoader imageLoader = new ImageLoader(mQueue, new ImageCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap getBitmap(String url) {
return null;
}
});
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
//BitmapCache的实现类
public class BitmapCache implements ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
int maxSize = 10 * 1024 * 1024;
mCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.fail_image);
imageLoader.get("http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg", listener);
imageLoader.get("http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg", listener, 600, 600);
public final boolean shouldCache() //查看是否已经做了磁盘缓存。 void setShouldCache(boolean shouldCache)//设置是否运行磁盘缓存,此方法需要在get方法前使用 public boolean isCached(String requestUrl, int maxWidth, int maxHeight)//判断对象是否已经被缓存,传入url,还有图片的最大宽高
创建一个RequestQueue对象。
创建一个ImageLoader对象。
在布局文件中添加一个NetworkImageView控件。
在代码中获取该控件的实例。
设置要加载的图片地址。
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal" />
/**创建RequestQueue以及ImageLoader对象**/
RequestQueue mQueue = Volley.newRequestQueue(context);
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
/**获取NetworkImageView控件**/
NetworkImageView networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
/**设置加载中显示的图片**/
networkImageView.setDefaultImageResId(R.drawable.default_image);
/**加载失败时显示的图片**/
networkImageView.setErrorImageResId(R.drawable.fail_image);
/**设置目标图片的URL地址**/
networkImageView.setImageUrl("http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg", imageLoader);
package com.android.volley.toolbox;
public class StringRequest extends Request<String> {
// 建立监听器来获得响应成功时返回的结果
private final Listener<String> mListener;
// 传入请求方法,url,成功时的监听器,失败时的监听器
public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) {
super(method, url, errorListener);
// 初始化成功时的监听器
mListener = listener;
}
/**
* Creates a new GET request.
* 建立一个默认的GET请求,调用了上面的构造函数
*/
public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected void deliverResponse(String response) {
// 用监听器的方法来传递下响应的结果
mListener.onResponse(response);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
// 调用了new String(byte[] data, String charsetName) 这个构造函数来构建String对象,将byte数组按照特定的编码方式转换为String对象,主要部分是data
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
}
public class XMLRequest extends Request<XmlPullParser> {
private final Listener<XmlPullParser> mListener;
public XMLRequest(int method, String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
@Override
protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
try {
String xmlString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlString));
return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (XmlPullParserException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(XmlPullParser response) {
mListener.onResponse(response);
}
}
XMLRequest xmlRequest = new XMLRequest("http://flash.weather.com.cn/wmaps/xml/china.xml",
new Response.Listener<XmlPullParser>() {
@Override
public void onResponse(XmlPullParser response) {
try {
int eventType = response.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String nodeName = response.getName();
if ("city".equals(nodeName)) {
String pName = response.getAttributeValue(0);
String cName = response.getAttributeValue(2);
showlog("省份:" + pName + " 城市:" + cName);
}
break;
}
eventType = response.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
showlog(error.getMessage());
}
});
mQueue.add(xmlRequest);
public class GsonRequest<T> extends Request<T> {
private final Listener<T> mListener;
private Gson mGson;
private Class<T> mClass;
public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
super(method, url, errorListener);
mGson = new Gson();
mClass = clazz;
mListener = listener;
}
public GsonRequest(String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {
this(Method.GET, url, clazz, listener, errorListener);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(mGson.fromJson(jsonString, mClass), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
{"weatherinfo":{"city":"上海","city_en":"","cityid":101020100,"date":"","date_y":"2016年09月20日","fchh":0,"fl1":"","fl2":"","fl3":"","fl4":"","fl5":"","fl6":"","fx1":"","fx2":"","img1":"1","img10":"1","img11":"1","img12":"1","img2":"1","img3":"1","img4":"1","img5":"1","img6":"1","img7":"1","img8":"1","img9":"1","img_single":0,"img_title1":"","img_title10":"","img_title11":"","img_title12":"","img_title2":"","img_title3":"","img_title4":"","img_title5":"","img_title6":"","img_title7":"","img_title8":"","img_title9":"","img_title_single":"","index":"","index48":"","index48_d":"","index48_uv":"","index_ag":"","index_cl":"","index_co":"","index_d":"","index_ls":"","index_tr":"","index_uv":"","index_xc":"","st1":0,"st2":0,"st3":0,"st4":0,"st5":0,"st6":0,"temp1":"20℃~28℃","temp2":"20℃~26℃","temp3":"19℃~26℃","temp4":"21℃~26℃","temp5":"23℃~28℃","temp6":"22℃~27℃","tempF1":"","tempF2":"","tempF3":"","tempF4":"","tempF5":"","tempF6":"","weather1":"多云","weather2":"多云","weather3":"多云","weather4":"多云","weather5":"多云","weather6":"多云","week":"","wind1":"","wind2":"","wind3":"","wind4":"","wind5":"","wind6":""}}
public class Weather {
public WeatherInfo weatherinfo;
}
public class WeatherInfo {
public String city;
public String cityid;
public String date_y;
public String temp1;
public String weather1;
}
GsonRequest<Weather> gsonRequest = new GsonRequest<Weather>(
"http://weather.51wnl.com/weatherinfo/GetMoreWeather?cityCode=101020100&weatherType=0", Weather.class,
new Response.Listener<Weather>() {
@Override
public void onResponse(Weather weather) {
WeatherInfo weatherInfo = weather.weatherinfo;
showlog("city is " + weatherInfo.city);
showlog("cityid is " + weatherInfo.cityid);
showlog("date_y is " + weatherInfo.date_y);
showlog("temp1 is " + weatherInfo.temp1);
showlog("weather1 is " + weatherInfo.weather1);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
showlog(error.getMessage());
}
});
mQueue.add(gsonRequest);
public class User {
private String name;
private int age;
}
public class GsonRequestWithAuth<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Listener<T> listener;
private Map<String, String> mHeader = new HashMap<String, String>();
private String mBody;
/** http请求编码方式 */
private static final String PROTOCOL_CHARSET = "utf-8";
/** 设置访问自己服务器时必须传递的参数,密钥等 */
static
{
mHeader.put("APP-Key", "Key");
mHeader.put("APP-Secret", "Secret");
}
/**
* @param url
* @param clazz 我们最终的转化类型
* @param listener
* @param appendHeader 附加头数据
* @param body 请求附带消息体
* @param errorListener
*/
public GsonRequestWithAuth(String url, Class<T> clazz, Listener<T> listener, Map<String, String> appendHeader, String body, ErrorListener errorListener) {
super(Method.POST, url, errorListener);
this.clazz = clazz;
this.listener = listener;
mHeader.putAll(appendHeader);
mBody = body;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
// 默认返回 return Collections.emptyMap();
return mHeader;
}
@Override
public byte[] getBody() {
try {
return mBody == null ? null : mBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mUserName, PROTOCOL_CHARSET);
return null;
}
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try
{
/** 得到返回的数据 */
String jsonStr = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
/** 转化成对象 */
return Response.success(gson.fromJson(jsonStr, clazz), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
}
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
/**获取APP-Key和APP-Secret */
String appKey = request.getHeader("APP-Key");
String appSecret = request.getHeader("APP-Secret");
/**获取用户名、密码 */
String username = request.getHeader("username");
String password = request.getHeader("password");
/**获取消息体 */
int size = request.getContentLength();
InputStream is = request.getInputStream();
byte[] reqBodyBytes = readBytes(is, size);
String body = new String(reqBodyBytes);
if ("admin".equals(username) && "123".equals(password) && "getUserInfo".equals(body)) {
response.setContentType("text/plain;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("{\"name\":\"Watson\",\"age\":28}");
out.flush();
}
}
}
Map<String, String> appendHeader = new HashMap<String, String>();
appendHeader.put("username", "admin");
appendHeader.put("password", "123");
String url = "http://172.27.35.1:8080/webTest/TestServlet";
GsonRequestWithAuth<User> userRequest = new GsonRequestWithAuth<User>(url, User.class, new Listener<User>() {
@Override
public void onResponse(User response)
{
Log.e("TAG", response.toString());
}
}, appendHeader, "getUserInfo", null);
mQueue.add(userRequest);
response.setContentType("text/plain;charset=utf-8");
public class CharsetStringRequest extends StringRequest {
public CharsetStringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
super(url, listener, errorListener);
}
public CharsetStringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String str = null;
try {
str = new String(response.data,"utf-8"); //在此处强制utf-8编码
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return Response.success(str, HttpHeaderParser.parseCacheHeaders(response));
}
}
CharsetStringRequest stringRequest = new CharsetStringRequest("http://www.weather.com.cn/data/sk/101010100.html",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
showlog(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
showlog(error.getMessage());
}
});
mQueue.add(userRequest);
public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, null);
}
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
//如果stack是等于null的,则去创建一个HttpStack对象,手机系统版本号是大于9的,则创建一个HurlStack的实例,否则就创建一个HttpClientStack的实例,HurlStack的内部就是使用HttpURLConnection进行网络通讯的,而HttpClientStack的内部则是使用HttpClient进行网络通讯的
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
//创建了一个Network对象,它是用于根据传入的HttpStack对象来处理网络请求的
Network network = new BasicNetwork(stack);
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start();
return queue;
}
public void start() {
stop(); // Make sure any currently running dispatchers are stopped.
//先是创建了一个CacheDispatcher的实例,然后调用了它的start()方法
mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
mCacheDispatcher.start();
//for循环创建NetworkDispatcher的实例,并分别调用它们的start()方法
for (int i = 0; i < mDispatchers.length; i++) {
NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
mDispatchers[i] = networkDispatcher;
networkDispatcher.start();
}
}
public <T> Request<T> add(Request<T> request) {
// Tag the request as belonging to this queue and add it to the set of current requests.
request.setRequestQueue(this);
synchronized (mCurrentRequests) {
mCurrentRequests.add(request);
}
// Process requests in the order they are added.
request.setSequence(getSequenceNumber());
request.addMarker("add-to-queue");
//判断当前的请求是否可以缓存,如果不能缓存则直接将这条请求加入网络请求队列
if (!request.shouldCache()) {
mNetworkQueue.add(request);
return request;
}
// Insert request into stage if there's already a request with the same cache key in flight.
synchronized (mWaitingRequests) {
String cacheKey = request.getCacheKey();
if (mWaitingRequests.containsKey(cacheKey)) {
// There is already a request in flight. Queue up.
Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey);
if (stagedRequests == null) {
stagedRequests = new LinkedList<Request<?>>();
}
stagedRequests.add(request);
mWaitingRequests.put(cacheKey, stagedRequests);
if (VolleyLog.DEBUG) {
VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);
}
} else {
//当前的请求可以缓存的话则将这条请求加入缓存队列
mWaitingRequests.put(cacheKey, null);
mCacheQueue.add(request);
}
return request;
}
}
public class CacheDispatcher extends Thread {
……
@Override
public void run() {
if (DEBUG) VolleyLog.v("start new dispatcher");
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
// Make a blocking call to initialize the cache.
mCache.initialize();
while (true) {
try {
// Get a request from the cache triage queue, blocking until
// at least one is available.
final Request<?> request = mCacheQueue.take();
request.addMarker("cache-queue-take");
// If the request has been canceled, don't bother dispatching it.
if (request.isCanceled()) {
request.finish("cache-discard-canceled");
continue;
}
//尝试从缓存当中取出响应结果
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
request.addMarker("cache-miss");
// 如何为空的话则把这条请求加入到网络请求队列中
mNetworkQueue.put(request);
continue;
}
// 如果不为空的话再判断该缓存是否已过期,如果已经过期了则同样把这条请求加入到网络请求队列中
if (entry.isExpired()) {
request.addMarker("cache-hit-expired");
request.setCacheEntry(entry);
mNetworkQueue.put(request);
continue;
}
//没有过期就认为不需要重发网络请求,直接使用缓存中的数据即可
request.addMarker("cache-hit");
//对数据进行解析
Response<?> response = request.parseNetworkResponse(
new NetworkResponse(entry.data, entry.responseHeaders));
request.addMarker("cache-hit-parsed");
if (!entry.refreshNeeded()) {
// Completely unexpired cache hit. Just deliver the response.
mDelivery.postResponse(request, response);
} else {
// Soft-expired cache hit. We can deliver the cached response,
// but we need to also send the request to the network for
// refreshing.
request.addMarker("cache-hit-refresh-needed");
request.setCacheEntry(entry);
// Mark the response as intermediate.
response.intermediate = true;
// Post the intermediate response back to the user and have
// the delivery then forward the request along to the network.
mDelivery.postResponse(request, response, new Runnable() {
@Override
public void run() {
try {
mNetworkQueue.put(request);
} catch (InterruptedException e) {
// Not much we can do about this.
}
}
});
}
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
return;
}
continue;
}
}
}
}
public class NetworkDispatcher extends Thread {
……
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
Request<?> request;
while (true) {
try {
// Take a request from the queue.
request = mQueue.take();
} catch (InterruptedException e) {
// We may have been interrupted because it was time to quit.
if (mQuit) {
return;
}
continue;
}
try {
request.addMarker("network-queue-take");
// If the request was cancelled already, do not perform the
// network request.
if (request.isCanceled()) {
request.finish("network-discard-cancelled");
continue;
}
addTrafficStatsTag(request);
//调用Network的performRequest()方法来去发送网络请求
NetworkResponse networkResponse = mNetwork.performRequest(request);
request.addMarker("network-http-complete");
// If the server returned 304 AND we delivered a response already,
// we're done -- don't deliver a second identical response.
if (networkResponse.notModified && request.hasHadResponseDelivered()) {
request.finish("not-modified");
continue;
}
// Parse the response here on the worker thread.
Response<?> response = request.parseNetworkResponse(networkResponse);
request.addMarker("network-parse-complete");
// Write to cache if applicable.
// TODO: Only update cache metadata instead of entire record for 304s.
if (request.shouldCache() && response.cacheEntry != null) {
mCache.put(request.getCacheKey(), response.cacheEntry);
request.addMarker("network-cache-written");
}
// Post the response back.
request.markDelivered();
mDelivery.postResponse(request, response);
} catch (VolleyError volleyError) {
parseAndDeliverNetworkError(request, volleyError);
} catch (Exception e) {
VolleyLog.e(e, "Unhandled exception %s", e.toString());
mDelivery.postError(request, new VolleyError(e));
}
}
}
}
public class BasicNetwork implements Network {
……
@Override
public NetworkResponse performRequest(Request<?> request) throws VolleyError {
long requestStart = SystemClock.elapsedRealtime();
while (true) {
HttpResponse httpResponse = null;
byte[] responseContents = null;
Map<String, String> responseHeaders = new HashMap<String, String>();
try {
// Gather headers.
Map<String, String> headers = new HashMap<String, String>();
addCacheHeaders(headers, request.getCacheEntry());
//调用了HttpStack的performRequest()方法,这里的HttpStack就是在一开始调用newRequestQueue()方法是创建的实例,默认情况下如果系统版本号大于9就创建的HurlStack对象,否则创建HttpClientStack对象
httpResponse = mHttpStack.performRequest(request, headers);
StatusLine statusLine = httpResponse.getStatusLine();
int statusCode = statusLine.getStatusCode();
responseHeaders = convertHeaders(httpResponse.getAllHeaders());
// Handle cache validation.
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
//将服务器返回的数据组装成一个NetworkResponse对象进行返回
return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
request.getCacheEntry() == null ? null : request.getCacheEntry().data,
responseHeaders, true);
}
// Some responses such as 204s do not have content. We must check.
if (httpResponse.getEntity() != null) {
responseContents = entityToBytes(httpResponse.getEntity());
} else {
// Add 0 byte response as a way of honestly representing a
// no-content request.
responseContents = new byte[0];
}
// if the request is slow, log it.
long requestLifetime = SystemClock.elapsedRealtime() - requestStart;
logSlowRequests(requestLifetime, request, responseContents, statusLine);
if (statusCode < 200 || statusCode > 299) {
throw new IOException();
}
return new NetworkResponse(statusCode, responseContents, responseHeaders, false);
} catch (Exception e) {
……
}
}
}
}
public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
request.markDelivered();
request.addMarker("post-response");
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
}
private class ResponseDeliveryRunnable implements Runnable {
private final Request mRequest;
private final Response mResponse;
private final Runnable mRunnable;
public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) {
mRequest = request;
mResponse = response;
mRunnable = runnable;
}
@SuppressWarnings("unchecked")
@Override
public void run() {
// If this request has canceled, finish it and don't deliver.
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}
// Deliver a normal response or error, depending.
if (mResponse.isSuccess()) {
mRequest.deliverResponse(mResponse.result);
} else {
mRequest.deliverError(mResponse.error);
}
// If this is an intermediate response, add a marker, otherwise we're done
// and the request can be finished.
if (mResponse.intermediate) {
mRequest.addMarker("intermediate-response");
} else {
mRequest.finish("done");
}
// If we have been provided a post-delivery runnable, run it.
if (mRunnable != null) {
mRunnable.run();
}
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有