Android Volley和Gson实现网络数据加载android
先看接口git
1 升级接口github
http://s.meibeike.com/mcloud/ota/cloudServicejson
POST请求缓存
参数列表以下网络
mainversion 1.0
commoninfo {"timestamp":"1450772874213","clientversion":"6.0","clientdescription":"goof","commonversion":"1.0","format":"json","clienttype":"3"}
json {"yunbangsn":"","pcode":"ncc","subversion":0,"clienttype":"3","innerversion":2015121821,"function":118}
返回信息以下session
{
"code": 0,
"type": "0",
"url": "http://d.meibeike.com/mcfs/ota/client/2015-12-18/CloudBar_2015121818_1.0.2.9.apk",
"function": 118,
"message": "成功获取版本信息",
"displayversion": "1.0.2.9",
"filesize": 6363546,
"subversion": 0,
"innerversion": 2015121818,
"updatemsg": "1.修改投射提示“USB导入出错”问题\r\n2.修改偶然性崩溃\r\n3.修改偶然性已绑定用户因为某些操做后变成了未绑定用户,数据丢失",
"updatemsg_cn": "1.修改投射提示“USB导入出错”问题\r\n2.修改偶然性崩溃\r\n3.修改偶然性已绑定用户因为某些操做后变成了未绑定用户,数据丢失",
"md5": "727c136c7914ffa8f480bf4d2037871d",
"updatemsg_tw": null,
"forceflag": "0"
}
上代码框架
public class MainActivity extends Activity { TextView show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show = (TextView)findViewById(R.id.show); Button test = (Button)findViewById(R.id.test); test.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RequestQueue queue = MyVolley.getRequestQueue(); GsonRequestNew<Cloud103Entity> myReq = new GsonRequestNew<Cloud103Entity>(Method.POST, "http://192.168.2.33:8084/mcloud/cloudclub/cloudService", Cloud103Entity.class, createMyReqSuccessListener(), createMyReqErrorListener()){ //传参数 protected Map<String, String> getParams() throws com.android.volley.AuthFailureError { Map<String, String> params = new HashMap<String, String>(); params.put("mainversion", "1.0"); params.put("commoninfo", getCommoninfo()); params.put("json", getJson()); Log.i("TAG", "发送参数" + params); return params; }; }; Log.i("TAG", "发送URL" + "http://192.168.2.33:8084/mcloud/cloudclub/cloudService"); queue.add(myReq); } }); } protected String getCommoninfo() { JSONObject commoninfo = new JSONObject(); try { commoninfo.put("commonversion", "1.0"); commoninfo.put("clienttype", "3"); commoninfo.put("clientversion", "6.0"); commoninfo.put("clientdescription", "goof"); commoninfo.put("timestamp", "1450765392640"); commoninfo.put("format", "json"); } catch (JSONException e) { Log.i("TAG", "e---" + e.getMessage()); } return commoninfo.toString(); } protected String getJson() { JSONObject json = new JSONObject(); try { json.put("function", 103); json.put("subversion", 0); json.put("userid", "mm730@mbk.com"); json.put("password", "e10adc3949ba59abbe56e057f20f883e"); json.put("accounttype", 0); } catch (JSONException e) { Log.i("TAG", "e---" + e.getMessage()); } return json.toString(); } private Response.Listener<Cloud103Entity> createMyReqSuccessListener() { return new Response.Listener<Cloud103Entity>() { @Override public void onResponse(Cloud103Entity response) { show.setText(response.getMessage()); } }; } private Response.ErrorListener createMyReqErrorListener() { return new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { show.setText(error.getMessage()); } }; } }
public class GsonRequestNew<T> extends Request<T> { private final Listener<T> mListener; private Gson mGson; private Class<T> mClass; public GsonRequestNew(int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) { super(method, url, errorListener); mGson = new Gson(); mClass = clazz; mListener = listener; } public GsonRequestNew(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)); Log.i("TAG", "响应" + jsonString); 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); } }
public class Cloud103Entity { private ArrayList<String> bindlist; private String message;// 返回信息 private String sessionkey;// 登陆成功后,后续操做以此sessionKey为准 private String username; private short subversion = 0;// 业务接口协议版本号 private String email;// email号码帐号 private long meiid;// 美贝壳内部id private int faceid;// 用户头像id private int code;// 返回码 private String faceurl;// 用户头像url private String mobile;// 手机号码帐号 private int function; public ArrayList<String> getBindlist() { return this.bindlist; } public void setBindlist(ArrayList<String> bindlist) { this.bindlist = bindlist; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public String getSessionkey() { return this.sessionkey; } public void setSessionkey(String sessionkey) { this.sessionkey = sessionkey; } public String getUsername() { return this.username; } public void setUsername(String username) { this.username = username; } public short getSubversion() { return this.subversion; } public void setSubversion(short subversion) { this.subversion = subversion; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } public long getMeiid() { return this.meiid; } public void setMeiid(long meiid) { this.meiid = meiid; } public int getFaceid() { return this.faceid; } public void setFaceid(int faceid) { this.faceid = faceid; } public int getCode() { return this.code; } public void setCode(int code) { this.code = code; } public String getFaceurl() { return this.faceurl; } public void setFaceurl(String faceurl) { this.faceurl = faceurl; } public String getMobile() { return this.mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public int getFunction() { return this.function; } public void setFunction(int function) { this.function = function; } /** * * { "bindlist": [ "C001B00010000008" ], "message": "登陆成功", "sessionkey": * "DC385A65D2FEA3FB2021F3F717B4FCD1", "username": "", "subversion": 0, * "email": "mm730@mbk.com", "meiid": 1000023, "faceid": 0, "code": 0, * "faceurl": "", "mobile": "", "function": "103" } */ }
public class MyApp extends Application{ @Override public void onCreate() { super.onCreate(); MyVolley.init(this); } }
public class MyVolley { private static RequestQueue mRequestQueue; static void init(Context context) { mRequestQueue = Volley.newRequestQueue(context); } public static RequestQueue getRequestQueue() { if (mRequestQueue != null) { return mRequestQueue; } else { throw new IllegalStateException("RequestQueue not initialized"); } } }
Code见 https://github.com/huanyi0723/VolleyGson/ide
Volley代码剖析
Volley
和 Volley 框架同名的类,实际上是个工具类,做用是构建一个可用于添加网络请求的 RequestQueue 对象
Request
网络请求的抽象类。咱们经过构建一个 Request 类的非抽象子类(StringRequest、JsonRequest、ImageRequest 或自定义)对象
Volley 支持 8 种 Http 请求方式 GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, PATCH
Request 类中包含了请求 url,请求请求方式,请求 Header,请求 Body,请求的优先级等信息
子类必须重写的两个方法
parseNetworkResponse() //将网络返回的原生字节内容,转换成合适的类型
deliverResponse() //将解析成合适类型的内容传递给它们的监听回调
getBody() //能够构建用于 POST、PUT、PATCH 请求方式的 Body 内容
getParams() // getBody 函数没有被重写状况下,此方法的返回值会被 key、value 分别编码后拼装起来转换为字节码做为 Body 内容
RequestQueue
Volley 框架的核心类,将请求 Request 加入到一个运行的 RequestQueue 中,来完成请求操做
mCacheQueue //缓存请求队列
mNetworkQueue //网络请求队列
mCurrentRequests //正在进行中,还没有完成的请求集合
mWaitingRequests //等待请求的集合
start() //开启一个缓存调度线程 CacheDispatcher 和 n 个网络调度线程 NetworkDispatcher ,这里 n 默认为 4
add() //加入请求
finish() //请求完成
cancelAll() //请求取消
CacheDispatcher
一个线程,用于调度处理走缓存的请求
mCacheQueue //缓存请求队列
mNetworkQueue //网络请求队列
mCache //表明了一个能够获取请求结果,存储请求结果的缓存
mDelivery //请求结果传递类
NetworkDispatcher
一个线程,用于调度处理走网络的请求
mQueue //网络请求队列
mNetwork //网络类,表明了一个能够执行请求的网络
mCache //缓存类
mDelivery //请求结果传递类
Cache
缓存接口,表明了一个能够获取请求结果,存储请求结果的缓存
get() //经过 key 获取请求的缓存实体
put() //存入一个请求的缓存实体
remove() //移除指定的缓存实体
clear() //清空缓存
内部类 Entry //表明缓存实体
data //请求返回的数据(Body 实体)
etag //Http 响应首部中用于缓存新鲜度验证的 ETag
serverDate //Http 响应首部中的响应产生时间
ttl //缓存的过时时间
softTtl //缓存的新鲜时间
responseHeaders //响应的 Headers
isExpired() //判断缓存是否过时,过时缓存不能继续使用
refreshNeeded() //判断缓存是否新鲜,不新鲜的缓存须要发到服务端作新鲜度的检测
DiskBasedCache
继承 Cache 类,基于 Disk 的缓存实现类
initialize() //初始化,扫描缓存目录获得全部缓存数据摘要信息放入内存
get() //从缓存中获得数据。先从摘要信息中获得摘要信息,而后读取缓存数据文件获得内容
put() //将数据存入缓存内。先检查缓存是否会满,会则先删除缓存中部分数据,而后再新建缓存文件
pruneIfNeeded() //检查是否能再分配 neededSpace 字节的空间,若是不能则删除缓存中部分数据
remove() //移除指定的缓存实体
clear() //清空缓存
内部类CacheHeader //缓存文件摘要信息,存储在缓存文件的头部
NoCache
继承 Cache 类,不作任何操做的缓存实现类,可将它做为构建 RequestQueue 的参数以实现一个不带缓存的请求队列函数
Network 表明网络的接口,处理网络请求 performRequest() //用于执行特定请求NetworkResponse Network 中方法 performRequest 的返回值 封装了网络请求响应的 StatusCode,Headers 和 Body 等 statusCode //Http 响应状态码 data //Body 数据 headers //表示是否为 304 响应 networkTimeMs //请求耗时 BasicNetwork Volley 中默认的网络接口实现类。调用 HttpStack 处理请求, 并将结果转换为可被 ResponseDelivery 处理的 NetworkResponseHttpStack 用于处理 Http 请求,返回请求结果的接口 performRequest() //执行 Request 表明的请求,第二个参数表示发起请求以前,添加额外的请求 HeadersHttpClientStack 实现 HttpStack 接口,利用 Apache 的 HttpClient 进行各类请求方式的请求HurlStack 实现 HttpStack 接口,利用 Java 的 HttpURLConnection 进行各类请求方式的请求Response 封装了通过解析后的数据,用于传输。 而且有两个内部接口 Listener 和 ErrorListener 分别可表示请求失败和成功后的回调。ByteArrayPool byte[] 的回收池,用于 byte[] 的回收再利用,减小了内存的分配和回收PoolingByteArrayOutputStream 继承 ByteArrayOutputStream,原始 ByteArrayOutputStream 中用于接受写入 bytes 的 buf, 每次空间不足时便会 new 更大容量的 byte[], 而 PoolingByteArrayOutputStream 使用了 ByteArrayPool 做为 Byte[] 缓存来减小这种操做,从而提升性能HttpHeaderParser Http header 的解析工具类,在 Volley 中主要做用是用于解析 Header 从而判断返回结果是否须要缓存, 若是须要返回 Header 中相关信息 parseDateAsEpoch() //解析时间,将 RFC1123 的时间格式,解析成 epoch 时间 parseCharset() //解析编码集,在 Content-Type 首部中获取编码集,若是没有找到,默认返回 ISO-8859-1 parseCacheHeaders() 经过网络响应中的缓存控制 Header 和 Body 内容,构建缓存实体。 若是 Header 的 Cache-Control 字段含有 no-cache 或 no-store 表示不缓存,返回 nullRetryPolicy 重试策略接口 getCurrentTimeout() //获取当前请求用时 getCurrentRetryCount() //获取已经重试的次数 retry() //肯定是否重试DefaultRetryPolicy Volley 默认的重试策略实现类 mCurrentRetryCount //已经重试次数 mBackoffMultiplier mCurrentTimeoutMs //当前重试的 timeout 时间ResponseDelivery 请求结果的传输接口,用于传递请求结果或者请求错误 postResponse() //此方法用于传递请求结果, request 和 response 参数分别表示请求信息和返回结果信息 postResponse() //此方法用于传递请求结果,并在完成传递后执行 Runnable postError() //传输请求错误ExecutorDelivery 请求结果传输接口具体实现类 在 Handler 对应线程中传输缓存调度线程或者网络调度线程中产生的请求结果或请求错误, 会在请求成功的状况下调用 Request.deliverResponse(…) 函数,失败时调用 Request.deliverError(…) 函数