編輯:關於Android編程
開發android應用很多時候都要涉及網絡操作,Android SDK中提供了HttpClient 和 HttpUrlConnection兩種方式用來處理網絡操作,但當應用比較復雜的時候需要我們編寫大量的代碼處理很多東西:圖像緩存,請求的調度等等;
而Volley框架就是為解決這些而生的,它與2013年Google I/O大會上被提出:使得Android應用網絡操作更方便更快捷;抽象了底層Http Client等實現的細節,讓開發者更專注與產生RESTful Request。另外,Volley在不同的線程上異步執行所有請求而避免了阻塞主線程。
目前的HTTP通信框架,AsyncHttpClient,網絡圖片加載框架,Universal-Image-Loader,而Volley是將以上兩個框架集於一身。
git clone https://android.googlesource.com/platform/frameworks/volley
或者使用我的地址,很久沒有更新了,請見諒,解決了SSL證書問題以及做了簡單的緩存
我一般都是使用封裝好的方法
封裝了返回Gson和String的get,post請求以及相應需要增加oauth驗證的方法
public class VolleyHttpClient { public static final int GET = 1; public static final int GET_AOUTH = 2; public static final int POST = 3; public static final int POST_AOUTH = 4; public static final int GETSTRING = 5; public static final int GETSTRING_AOUTH = 6; public static final int POSTSTRING_AOUTH = 7; private static final String TAG = "VolleyHttpClient"; private static HttpService httpService; private final static Gson gson = new Gson(); private static BaseActivity activity; public VolleyHttpClient(HttpService httpService) { this.httpService = httpService; } /** * 傳入初始化好的httpService 實例 * * @param httpService * @return */ public static VolleyHttpClient newInstance(HttpService httpService, Context context) { activity = (BaseActivity) context; if (httpService != null) { return new VolleyHttpClient(httpService); } return null; } public void post(ApiRequest apiRequest) { doNetTask(POST, apiRequest, DataCacheType.NO_CACHE); } public void postWithOAuth(ApiRequest apiRequest) { doNetTask(POST_AOUTH, apiRequest, DataCacheType.NO_CACHE); } public void get(ApiRequest apiRequest) { doNetTask(GET, apiRequest, DataCacheType.NO_CACHE); } public void getWithOAuth(ApiRequest apiRequest) { doNetTask(GET_AOUTH, apiRequest, DataCacheType.NO_CACHE); } public void doNetTask(int method, ApiRequest apiRequest) { doNetTask(method, apiRequest, DataCacheType.NO_CACHE); } public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType) { doNetTask(method, apiRequest, cacheType, false, null); } public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType, boolean needLogin, BaseActivity activity) { doNetTask(method, apiRequest, cacheType, needLogin, activity, false); } public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType, boolean needLogin, BaseActivity activity, boolean needFinish) { if (needLogin && activity.app.getUserParam() == null) { try { activity.cancelLoadingDialog(); } catch (Exception e) { e.printStackTrace(); } Intent intent = new Intent(activity, LoginActivity_.class); activity.startActivity(intent); if (needFinish) { activity.finish(); } return; } switch (method) { case GET: //USER_OLD_CACHE有緩存先加載緩存數據,然後網絡請求只是保存數據 //TEMP_CACHE有緩存先加載緩存數據,不進行網絡請求 get(apiRequest, false, cacheType); break; case GET_AOUTH: get(apiRequest, true, cacheType); break; case POST: post(apiRequest, false, cacheType); break; case POST_AOUTH: post(apiRequest, true, cacheType); break; case GETSTRING: getByStringRequest(apiRequest, false, cacheType); break; case GETSTRING_AOUTH: getByStringRequest(apiRequest, true, cacheType); break; case POSTSTRING_AOUTH: postByStringRequest(apiRequest, true, cacheType); break; } } /** * 不用傳header以及accesstoken的GET請求 * * @param apiRequest */ public void get(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) { Mapheader = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); if (needOauth) { String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } if (!TextUtils.isEmpty(accessToken)) { LogUtils.e("access_token", accessToken); } // header.put("Authorization", "Bearer" + " " + accessToken); header.put("token", accessToken); } String url = apiRequest.getUrl(Method.GET); Listener listener = apiRequest.getListener(); LogUtils.e("------cacheType---------", cacheType.name()); switch (cacheType) { case USE_OLD_CACHE: case TEMP_CACHE: String cacheStr =""; if(cacheType == DataCacheType.TEMP_CACHE){ cacheStr = DataCache.getDataCache().queryTempCache(url); }else { cacheStr = DataCache.getDataCache().queryCache(url); } if (!TextUtils.isEmpty(cacheStr)) { try { if (apiRequest.getResponseType() != null) { //有緩存先加載緩存數據 listener.onResponse(gson.fromJson(cacheStr, apiRequest.getResponseType())); //有緩存先加載緩存數據,不進行網絡請求 if (cacheType == DataCacheType.TEMP_CACHE) { return; } } else { listener.onResponse(cacheStr); if (cacheType == DataCacheType.TEMP_CACHE) { return; } } } catch (JsonSyntaxException e) { e.printStackTrace(); } } break; default: break; } GsonRequest request = new GsonRequest(Method.GET, url, apiRequest.getResponseType(), header, null, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); //網絡錯誤並且使用TEMP_CACHE和use old cache還有待考察 if (!useCache(apiRequest.getResponseType(), url, listener)) { httpService.addToRequestQueue(request); } } public void post(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) { Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); if (needOauth) { String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } if (!TextUtils.isEmpty(accessToken)) { LogUtils.e("access_token", accessToken); } // header.put("Authorization", "Bearer" + " " + accessToken); header.put("token", accessToken); } LogUtils.e("------cacheType---------", cacheType.name()); String url = apiRequest.getUrl(Request.Method.POST); Listener listener = apiRequest.getListener(); if (apiRequest.getParams() != null && apiRequest.getParams().size() > 0) { //post有參數時候請求不建議使用use_old_cache方式,因為根據路徑存儲,post參數不在路徑中 if (cacheType == DataCacheType.USE_OLD_CACHE) { cacheType = DataCacheType.CACHE; } } switch (cacheType) { case USE_OLD_CACHE: case TEMP_CACHE: String cacheStr = DataCache.getDataCache().queryCache(url); if (!TextUtils.isEmpty(cacheStr)) { try { if (apiRequest.getResponseType() != null) { //有緩存先加載緩存數據 listener.onResponse(gson.fromJson(cacheStr, apiRequest.getResponseType())); //有緩存先加載緩存數據,不進行網絡請求 if (cacheType == DataCacheType.TEMP_CACHE) { return; } } else { listener.onResponse(cacheStr); if (cacheType == DataCacheType.TEMP_CACHE) { return; } } } catch (JsonSyntaxException e) { e.printStackTrace(); } } break; default: break; } GsonRequest request = new GsonRequest(Request.Method.POST, url, apiRequest.getResponseType(), header, apiRequest.getParams(), listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); //網絡錯誤並且使用TEMP_CACHE和use old cache還有待考察 if (!useCache(apiRequest.getResponseType(), url, listener)) { httpService.addToRequestQueue(request); } } /** * 圖片請求 */ public ImageLoader.ImageContainer loadingImage(ImageView imageView, String url, int loadingResid, int errorResid, BitmapCache mCache, ImageLoader.ImageListener listener) { if (listener == null) { listener = ImageLoader.getImageListener(imageView, loadingResid, errorResid); } if (httpService.httpQueue != null) { ImageLoader imageLoader = new ImageLoader(httpService.httpQueue, mCache); return imageLoader.get(url, listener); } return null; } public void loadingImage(ImageView imageView, String url, int loadingResid, int errorResid, BitmapCache mCache) { loadingImage(imageView, url, loadingResid, errorResid, mCache, null); } /** * StringRequest */ public void getByStringRequest(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) { Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); if (needOauth) { String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } if (!TextUtils.isEmpty(accessToken)) { LogUtils.e("access_token", accessToken); } // header.put("Authorization", "Bearer" + " " + accessToken); header.put("token", accessToken); } String url = apiRequest.getUrl(Request.Method.GET); Listener listener = apiRequest.getListener(); StringRequest request = new StringRequest(Request.Method.GET, url, header, null, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); if (!useCache(null, url, listener)) { httpService.addToRequestQueue(request); } } /** * StringRequest */ public void postByStringRequest(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) { Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); String url = apiRequest.getUrl(Request.Method.POST); Listener listener = apiRequest.getListener(); if (needOauth) { String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } if (!TextUtils.isEmpty(accessToken)) { LogUtils.e("access_token", accessToken); } // header.put("Authorization", "Bearer" + " " + accessToken); header.put("token", accessToken); } Map params = new HashMap (); for (String key : apiRequest.getParams().keySet()) { params.put(key, (String) apiRequest.getParams().get(key)); } StringRequest request = new StringRequest(Request.Method.POST, url, header, params, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); if (!useCache(null, url, listener)) { httpService.addToRequestQueue(request); } } /** * 斷網情況使用緩存處理 * * @param clazz * @param url * @param listener * @return */ private boolean useCache(Class clazz, String url, Listener listener) { HttpService.httpQueue.getCache().invalidate(url, true); if (!NetWorkUtils.detect(httpService.getContext())) { String cacheStr = DataCache.getDataCache().queryCache(url); if (cacheStr != null) { try { if (clazz != null) { listener.onResponse(gson.fromJson(cacheStr, clazz)); } else { listener.onResponse(cacheStr); } return true; } catch (JsonSyntaxException e) { e.printStackTrace(); return false; } } return false; } else { return false; } } public void getExtWithOAuth(com.core.api.event.request.Request apiRequest) { getExtWithOAuth(apiRequest, DataCacheType.NO_CACHE); } public void getExtWithOAuth(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) { String url = apiRequest.getUrl(Request.Method.GET) + "?" + apiRequest.httpParam.encodeParametersToString("UTF-8"); Listener listener = apiRequest.getListener(); Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } header.put("token", accessToken); GsonRequestExt request = new GsonRequestExt(Request.Method.GET, url, apiRequest.getResponseType(), header, apiRequest.httpParam, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); if (!useCache(apiRequest.getResponseType(), url, listener)) { httpService.addToRequestQueue(request); } } public void getExt(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) { Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); String url = apiRequest.getUrl(Request.Method.GET) + "?" + apiRequest.httpParam.encodeParametersToString("UTF-8"); Listener listener = apiRequest.getListener(); GsonRequestExt request = new GsonRequestExt(Request.Method.GET, url, apiRequest.getResponseType(), header, apiRequest.httpParam, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); if (!useCache(apiRequest.getResponseType(), url, listener)) { httpService.addToRequestQueue(request); } } public void postExt(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) { Map header = new HashMap (); if (apiRequest.getHeaders() != null) { header.putAll(apiRequest.getHeaders()); } header.put("code", ApiSettings.VERSION_CODE); header.put("osType", ApiSettings.OSTYPE); String accessToken = GlobalPhone.token; if(TextUtils.isEmpty(accessToken)){ accessToken = DataCache.getDataCache() .queryCache("access_token"); } if (!TextUtils.isEmpty(accessToken)) { header.put("token", accessToken); } String url = apiRequest.getUrl(Request.Method.POST); Listener listener = apiRequest.getListener(); GsonRequestExt request = new GsonRequestExt(Request.Method.POST, url, apiRequest.getResponseType(), header, apiRequest.httpParam, listener, apiRequest.getErrorlistener(), cacheType); request.setShouldCache(false); if (!useCache(apiRequest.getResponseType(), url, listener)) { httpService.addToRequestQueue(request); } } // volley框架緩存 // if (HttpService.httpQueue.getCache().get(url) != null) { // String cacheStr = new String(HttpService.httpQueue.getCache() // .get(url).data); // // if (cacheStr != null) { // // try { // listener.onResponse(cacheStr); // // } catch (JsonSyntaxException e) { // e.printStackTrace(); // } // // return; // } // // } }
public class ApiRequest { public String url = ""; protected Map創建相應的request,ApiConstans中存放所有請求的路徑params = null; private Class clazz; private Response.Listener listener; private Response.ErrorListener errorlistener; protected Map headers; public ApiRequest(String values, Class clazz) { this(values, clazz, false); } public ApiRequest(String values, Class clazz, boolean isChonggou) { if (isChonggou) { this.url = values; } else { this.url = String.format("%1$s%2$s", ApiSettings.URL_BASE, values); } this.clazz = clazz; this.params = new HashMap (); // params.put("versionCode",ApiSettings.VERSION_CODE); this.headers = new HashMap (); } public String getUrl(int method) { switch (method) { case Method.GET: return urlWithParameters(url, params); case Method.POST: return url; } return url; } public Map getParams() { if (params.isEmpty()) { Log.e("REQUEST_PARAMS", "null"); return null; } return params; } public void setParams(Map params) { this.params = params; } public Class getResponseType() { return clazz; } public Response.Listener getListener() { return listener; } public void setListener(Response.Listener listener) { this.listener = listener; } public Response.ErrorListener getErrorlistener() { return errorlistener; } public void setErrorlistener(Response.ErrorListener errorlistener) { this.errorlistener = errorlistener; } public Map getHeaders() { if (headers.isEmpty()) { Log.e("REQUEST_Header", "null"); return null; } return headers; } public void setHeaders(Map headers) { this.headers = headers; } public void addParams(Map params) { if (this.params != null) { this.params.putAll(params); } else { this.params = new HashMap (); this.params.putAll(params); } } public static String urlWithParameters(String url, Map params) { StringBuilder builder = new StringBuilder(); if (params != null) { for (HashMap.Entry entry : params.entrySet()) { if (builder.length() == 0) { if (url.contains("?")) { builder.append("&"); } else { builder.append("?"); } } else { builder.append("&"); } builder.append(entry.getKey()).append("=") .append(entry.getValue()); } } return url + builder.toString(); } }
public class AnswerListRequest extends ApiRequest implements ApiConstants { public AnswerListRequest(int page,int pageSize) { super(API_ANSWERLIST, AnswerListResponse.class); params.put("page",page); params.put("pageSize",pageSize); } }
當然,所有請求可以放到一個library包,做抽離
一個類似於進度和打卡進度的自定義view如下圖:看GIF豈不是更好這個view在現在的app中挺常見的,基本都是這個套路,之前寫過一個可以雙向滑動的和這個view的類似,
RatingBar介紹 RatingBar作為評分組件,它在實現打分功能的時候確實很方便,並結合了手勢觸摸事件;RatingBar 的實質是 ProgressBar ,可
前言:從Android Studio開始,就支持jni和.so庫調用了。環境:Windows 7+Android Studio2.1.2+NDK版本:android-nd
本文實例總結了Android編程中圖片特效處理方法。分享給大家供大家參考,具體如下:這裡介紹的Android圖片處理方法包括:轉換 - drawable To