Volley secondary encapsulation and implement network request cache in Android
Currently, many students use Volley to request network data, but Volley does not cache the requested data, so we need to manually cache it ourselves. Here is my idea, for reference only
The specific usage method is:
HashMap<String,String> params = new HashMap<>(); ("id", "1"); ("user", "mcoy"); new NetWorkHelper(getActivity()).jacksonMethodRequest ("method_id", params, new TypeReference<ReturnTemple<FirstCategories>>(){}, handler, msgId);
NetWorkHelper---Insert Volley, first call (methodName, params); method to obtain the cached data. If the data is null,
Continue to send network requests.
/** * @version V1.0 Network request help class * @author: mcoy */ public final class NetWorkHelper { private NetWorkManager netWorkUtils; public NetWorkHelper(Context context){ netWorkUtils = new NetWorkManager(context); } public static final String COMMON_ERROR_MSG = "Connection timed out, please try again later"; public static final int COMMON_ERROR_CODE = 2; /** * Methods using Jackson requests * @param methodName * @param params * @param handler * @param msgId */ public void jacksonMethodRequest(final String methodName,final HashMap<String,String> params,TypeReference javaType, final Handler handler,final int msgId){ ResponseListener listener = new ResponseListener(){ @Override public void onResponse(Object response, boolean isCache) { (()); if (isCache){ (methodName, params, response); } if (handler != null) { Message message = (); = msgId; = response; (message); } } }; Object respone = (methodName, params); if(respone != null){ (respone,false); return; } HashMap<String,String> allParams = (true); (params); errorListener = new () { @Override public void onErrorResponse(VolleyError error) { (); if (handler != null) { Message message = (); = msgId; = COMMON_ERROR_MSG; (message); } } }; (getUrl(methodName), allParams,javaType, listener, errorListener); } /** * Url direct request * @param url * @param params * @param handler * @param msgId */ public void urlRequest(String url,HashMap<String,String> params,JsonParser jsonParser,final Handler handler,final int msgId){ request(url, true, params, jsonParser, handler, msgId); } /** * Request via method * @param methodName methodName * @param params Request parameters * @param jsonParser Json parser * @param handler callback notification * @param msgId Notified Id */ public void methodRequest(String methodName, final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){ request(getUrl(methodName),true,params,jsonParser,handler,msgId); } /** * Request via method * @param methodName methodName * @param params Request parameters * @param jsonParser Json parser * @param handler callback notification * @param msgId Notified Id */ public void methodRequest(String methodName, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){ request(getUrl(methodName),isLogin,params,jsonParser,handler,msgId); } private void request(final String url, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){ final HashMap<String,String> allParams = (isLogin); (params); listener = new <String>() { @Override public void onResponse(String response) { /** * Some requests are not transmitted by parser by default. Only String is required for outgoing parameters, such as joint login, etc. * So added an else if */ Object result; (response); if (jsonParser != null ) { jsonParser.json2Obj(response); = (); result = ; } else { ReturnTemple temple = new ReturnTemple(); = false; = COMMON_ERROR_MSG; = -100; result = temple; } if (handler != null) { Message message = (); = msgId; = result; (message); } } }; errorListener = new () { @Override public void onErrorResponse(VolleyError error) { Object result; if (jsonParser != null) { ReturnTemple temple = new ReturnTemple(); = false; = COMMON_ERROR_MSG; = COMMON_ERROR_CODE; result = temple; } else { result = COMMON_ERROR_MSG; } if (handler != null) { Message message = (); = msgId; = result; (message); } } }; (url, allParams, listener, errorListener); } /** *Url according to the name request * @param methodName * @return */ private String getUrl(String methodName){ String url = (); if (!(methodName)) { url = url + "?method=" + methodName; } return url; } }
CacheManager---Cache requested data for a method to a local file, mainly writing CacheRule to the local file
/** * @version V1.0 <Cache Management> * @author: mcoy */ public final class CacheManager { /** * Multiple keys corresponding to a method, such as the classification is the same method, but the requests will be different, and they may all need to be cached. */ private static HashMap<String, ArrayList<String>> methodKeys; private static final String keyFileName = ""; /** * Read cached Key */ public static void readCacheKey() { methodKeys = (HashMap<String, ArrayList<String>>) readObject(keyFileName); if (methodKeys == null) { methodKeys = new HashMap<String, ArrayList<String>>(); } } /** * Save cache */ public static void put(String method, HashMap<String, String> params, Object object) { long expireTime = (method); if (expireTime <= 0 || methodKeys == null) {//The valid time is less than 0, no cache is required return; } String key = createKey(method, params); if ((method)) { ArrayList<String> keys = (method); (key); } else { ArrayList<String> keys = new ArrayList<>(); (key); (method, keys); } writeObject(methodKeys, keyFileName); String fileName = key + ".pro"; CacheRule cacheRule = new CacheRule(expireTime, object); (" put " + method + " " + key + " " + cacheRule); writeObject(cacheRule, fileName); } public static Object get(String method, HashMap<String, String> params) { long expireTime = (method); if (expireTime <= 0 || methodKeys == null || !(method)) {//The valid time is less than 0, no cache is required return null; } ArrayList<String> keys = (method); // String saveKey = (method); String key = createKey(method, params); String fileName = key + ".pro"; // ("get"+method+" "+((key))+" path:"+fileName); CacheRule cacheRule = null; try { if ((key)) { cacheRule = (CacheRule) readObject(fileName); } } catch (Exception e) { (); } ("get :" + method + " " + key + " " + cacheRule); if (cacheRule != null && ()) { return (); } else { return null; } } public static void main(String[] args) { String method = ""; HashMap<String, String> params = new HashMap<>(); ("categoryId", "-3"); (createKey(method, params)); (()); } /** * Generate Key * * @param method The method requested * @param params Private parameters (parameters other than public parameters) * @return */ private static String createKey(String method, HashMap<String, String> params) { try { MessageDigest digest = ("md5"); (("UTF-8")); StringBuilder builder = new StringBuilder(method); if (params != null && () > 0) { Iterator<<String, String>> iterator = ().iterator(); while (()) { <String, String> entry = (); (()).append("=").append(()); } } byte[] tempArray = (().getBytes("UTF-8")); StringBuffer keys = new StringBuffer(); for (byte b : tempArray) { // with operations int number = b & 0xff;// With salt String str = (number); // (str); if (() == 1) { ("0"); } (str); } return ().toUpperCase(); } catch (Exception e) { (); } return (); } /** * Write the object to the file * * @param object * @param fileName */ private static void writeObject(Object object, String fileName) { try { ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File(() + fileName))); (object); (); } catch (IOException e) { (); } } /** * Read the object * * @param fileName * @return */ private static Object readObject(String fileName) { Object result = null; try { File file = new File(() + fileName); if (()) { ObjectInputStream oi = new ObjectInputStream(new FileInputStream(file)); result = (); (); } } catch (Exception e) { (); } return result; } }
CacheConfig---What methods of initialization need to be cached and the validity time of cache
/** * @version V1.0 <Set what types of data need to be cached> * @author: mcoy */ public final class CacheConfig { /**The cache valid time corresponding to the method is milliseconds*/ private static HashMap<String,Long> methodExpireTimes = new HashMap<String, Long>(); private static String cachePath = null; static { (ConstMethod.GET_CATEGORY_LIST,30 * 60 * 1000L); (ConstMethod.GET_NEW_CATEGORY_LIST,30 * 60 * 1000L); } /** * Initialize the cache path * @param context */ public static void init(Context context){ cachePath = ().getPath()+ +"cache"+; File file = new File(cachePath); if(!()){ (); } (); } /**Cached path*/ public static String getCachePath() { return cachePath; } /** * Get the valid time corresponding to a method. If the method does not add a cache or the cache time is less than 0, no cache will be added. * @param method * @return */ public static long getExpireTime(String method){ if((method)){ return (method); }else { return -1; } } }
CacheRule---There are two main parameters: ExpireTime needs to be cached, and data needs to be cached.
public class CacheRule implements Serializable{ /** Valid time */ public long expireTime; /** Cache time*/ public long cacheTime; /** Cache data */ private Object data; public CacheRule(long expireTime,Object data){ cacheTime = getCurrentTime(); = expireTime; = data; } public Object getData() { return data; } public void setData(Object data) { = data; } @Override public int hashCode() { return (expireTime, cacheTime, data); } @Override public String toString() { StringBuilder builder = new StringBuilder(); ("expireTime:").append(expireTime).append(" cacheTime:").append(cacheTime) .append(" curTime:").append(getCurrentTime()) .append(" isExpire:").append(isExpire()).append(" data:").append(data==null?"null":()); return (); } /** * Is the data valid? * @return */ public boolean isExpire(){ long curTime = getCurrentTime(); return curTime>(expireTime+cacheTime)?false:true; } /** * Get the current time * @return */ public static long getCurrentTime(){ // if (Build.VERSION_CODES.JELLY_BEAN_MR1 <= .SDK_INT) { // return (); // } else { return (); // } } }
NetWorkManager---Add JacksonRequest request to the RequestQueue, and then Volley will request data
/** * Web request tool class */ public final class NetWorkManager { private RequestQueue requestQueue ; public NetWorkManager(Context context){ requestQueue = (context); } /** * Methods to parse requests using Jackson * @param url * @param params * @param javaType Java type returned when successful * @param listener * @param errorListener */ public void jacksonRequest(final String url,final HashMap<String,String> params,TypeReference javaType, ResponseListener listener, errorListener){ JacksonRequest jacksonRequest = new JacksonRequest(url,javaType,params,listener,errorListener); (jacksonRequest); } /** * Normal network request, returned Json * @param url * @param params * @param listener * @param errorListener */ public void request(final String url,final HashMap<String,String> params, listener, errorListener){ StringRequest stringRequest = new StringRequest(,url,listener,errorListener){ @Override protected Map<String, String> getParams() throws AuthFailureError { if () { Iterator<<String,String>> iterator = ().iterator(); StringBuilder builder = new StringBuilder(url+" "); while (()){ <String,String> entry = (); (()+":"+()).append("; "); } (()); } return params; } }; (stringRequest); } }
JacksonRequest---Inherit Request, override the deliverResponse method, and call the onResponse method of ResponseListener, and cache the obtained response to the CacheManager through (methodName, params, response);. This step is important, calling our own listener, not what Volley provides us with
/** * Created by mcoy */ public class JacksonRequest extends Request { private final HashMap<String,String> params; private final ResponseListener listener; private final ObjectMapper mapper; private final TypeReference javaType; public JacksonRequest(String url,TypeReference javaType,HashMap<String,String> params,ResponseListener listener, errorListener){ super(,url,errorListener); mapper = new ObjectMapper(); (.ALLOW_SINGLE_QUOTES,true); (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); = params; = listener; = javaType; } @Override protected Map<String, String> getParams() throws AuthFailureError { return params; } @Override protected Response parseNetworkResponse(NetworkResponse response) { String json; try { json = new String(, ()); ("Returned json:" + json); return ((json,javaType), (response)); }catch (UnsupportedEncodingException e){ json = new String(); ("json:"+json); try { return ((json,javaType),(response)); } catch (IOException e1) { return (new ParseError(e)); } } catch (JsonParseException e) { (()); return (new ParseError(e)); } catch (JsonMappingException e) {(()); return (new ParseError(e)); } catch (IOException e) {(()); return (new ParseError(e)); } } @Override protected void deliverResponse(Object response) { (response,true); } }
ResponseListener---A custom listener interface, it needs to be implemented when sending a request. The listener provided by Volley in the parameter isCache Boolean value, and based on this value, determine whether to cache.
/** * @version V1.0 <Describe the current version function> * @author: mcoy */ public interface ResponseListener<T> { public void onResponse(T response, boolean isCache); }
If you have any questions, please leave a message or go to the community of this site to exchange and discuss. Thank you for reading. I hope it can help you. Thank you for your support for this site!