amurocrash的专栏

产品中使用Volley框架已有多时,本身已有良好封装的Volley确实给程序开发带来了很多便利与快捷。但随着产品功能的不断增加,服务器接口的不断复杂化,直接使用Volley原生的JSONObjectRequest已经导致Activity或Fragment层中耦合了大量的数据解析代码,同时当多处调用同一接口时,类似的数据解析代码还不可复用,导致大量重复代码的出现,已经让我越发地无法忍受。基于此,最近思考着对Volley原生的JSONObjectRequest(因为产品中目前和服务器交互所有的接口,数据都是json格式的)进行二次封装,把Activity和Fragment中大量的数据解析代码剥离出来,同时实现数据解析代码的复用。

为了把问题表现出来,,先上一段坑爹的代码。

package com.backup;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import org.json.JSONException;import org.json.JSONObject;import com.amuro.volleytest01_image.R;import com.android.volley.RequestQueue;import com.android.volley.Response;import com.android.volley.VolleyError;import com.android.volley.toolbox.JsonObjectRequest;import com.android.volley.toolbox.Volley;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;public class TestActivity02 extends Activity{private RequestQueue mQueue;private ListView listView;private List<Map<String, String>> list = new ArrayList<Map<String,String>>();String url = ":8081/weather.html";@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_test02_layout);listView = (ListView)findViewById(R.id.lv_test02);mQueue = Volley.newRequestQueue(this);getWeatherInfo();SimpleAdapter simpleAdapter = new SimpleAdapter(this, list,android.R.layout.simple_list_item_2, new String[] {"title","content"},new int[] {android.R.id.text1, android.R.id.text2});listView.setAdapter(simpleAdapter);listView.setOnItemClickListener(new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id){TextView tv = (TextView)view.findViewById(android.R.id.text1);tv.setText("111111111111111111");}});}public void getWeatherInfo(){JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, null,new Response.Listener<JSONObject>(){@SuppressWarnings("unchecked")@Overridepublic void onResponse(JSONObject jsonObject){list.clear();Iterator<String> it = jsonObject.keys();while (it.hasNext()){String key = it.next();JSONObject obj = null;try{obj = jsonObject.getJSONObject(key);}catch (JSONException e){e.printStackTrace();}if (obj != null){Iterator<String> objIt = obj.keys();while (objIt.hasNext()){String objKey = objIt.next();String objValue;try{objValue = obj.getString(objKey);HashMap<String, String> map = new HashMap<String, String>();map.put("title", objKey);map.put("content", objValue);list.add(map);}catch (JSONException e){e.printStackTrace();}}}}}},new Response.ErrorListener(){@Overridepublic void onErrorResponse(VolleyError arg0){}});mQueue.add(jsonObjectRequest);}}<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span><span style="font-family:Arial;BACKGROUND-COLOR: #ffffff">上面的代码大家可以看到,复杂的json解析代码全部写在Activity里,现在如果又来一个Activity需要调用这个接口,这些解析json的代码是完全无法复用的,这不科学~</span><span style="font-family:Arial;BACKGROUND-COLOR: #ffffff">好,下面开始装逼,哦不,分析:</span><span style="font-family:Arial;BACKGROUND-COLOR: #ffffff">1. 面向对象,对于Activity这层来说,它要的只是拿到数据进行展示,至于数据怎么变出来的,它不应该关注,所以第一件事,对数据进行封装,每个接口返回的最终数据,不应该是一个未经解析的jsonObject,而应该是一个bean,千千万万的bean最终可通过泛型来统一,so,我们先需要一个监听器,让我们封装后的Volley层直接把bean回调给Activity。</span><span style="font-family:Arial;BACKGROUND-COLOR: #ffffff">2. 对错误的处理,从目前的产品需求来看,上层Activity就是要对不同的错误展示不同的界面或跳转不同的界面,所以我们把错误统一为errorCode和errorMessage,在底层封装好后,直接抛给Activity。所以这样一个返回bean或者error的接口就出来了。</span>package com.amuro.volley_framwork.network_helper;public interface UIDataListener<T>{public void onDataChanged(T data);public void onErrorHappened(String errorCode, String errorMessage);}

3. 好,监听器剥离了Activity与我们的Volley层,下面我们就要自己对Volley的JsonObjectRequest进行封装了,先贴这个类:

package com.amuro.volley_framwork.network_request;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.List;import java.util.Map;import org.apache.http.NameValuePair;import org.apache.http.client.utils.URLEncodedUtils;import org.json.JSONObject;import com.android.volley.DefaultRetryPolicy;import com.android.volley.NetworkResponse;import com.android.volley.ParseError;import com.android.volley.Response;import com.android.volley.Response.ErrorListener;import com.android.volley.Response.Listener;import com.android.volley.toolbox.HttpHeaderParser;import com.android.volley.toolbox.JsonRequest;public class NetworkRequest extends JsonRequest<JSONObject>{private Priority mPriority = Priority.HIGH;public NetworkRequest(int method, String url,Map<String, String> postParams, Listener<JSONObject> listener,ErrorListener errorListener) {super(method, url, paramstoString(postParams), listener, errorListener);setRetryPolicy(new DefaultRetryPolicy(30000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));}public NetworkRequest(String url, List<NameValuePair> params,Listener<JSONObject> listener, ErrorListener errorListener) {this(Method.GET, urlBuilder(url, params), null, listener, errorListener);}public NetworkRequest(String url, Listener<JSONObject> listener, ErrorListener errorListener) {this(Method.GET, url, null, listener, errorListener);}private static String paramstoString(Map<String, String> params){if (params != null && params.size() > 0){String paramsEncoding = "UTF-8";StringBuilder encodedParams = new StringBuilder();try{for (Map.Entry<String, String> entry : params.entrySet()){encodedParams.append(URLEncoder.encode(entry.getKey(),paramsEncoding));encodedParams.append('=');encodedParams.append(URLEncoder.encode(entry.getValue(),paramsEncoding));encodedParams.append('&');}return encodedParams.toString();}catch (UnsupportedEncodingException uee){throw new RuntimeException("Encoding not supported: "+ paramsEncoding, uee);}}return null;}@Overrideprotected Response<JSONObject> parseNetworkResponse(NetworkResponse response){try{JSONObject jsonObject = new JSONObject(new String(response.data, "UTF-8"));return Response.success(jsonObject,HttpHeaderParser.parseCacheHeaders(response));}catch (Exception e){return Response.error(new ParseError(e));}}@Overridepublic Priority getPriority(){return mPriority;}public void setPriority(Priority priority){mPriority = priority;}private static String urlBuilder(String url, List<NameValuePair> params) {return url + "?" + URLEncodedUtils.format(params, "UTF-8");}}找寻隐藏在山间的纯净和那“鸟鸣山更幽”的飞鸟。

amurocrash的专栏

相关文章:

你感兴趣的文章:

标签云: