[转载]Android在AsyncHttpClient框架的基础上定制能直接返回对象数组的框架 – JamesXu的专栏 – 博客频道 – CSDN.NET.
以前听一个大神说过一句借用不知道哪位伟人的话:一个好的方法只有两三行,每个方法只专注一件事。
本 着这样的精神,我们在拉取网路数据的时候希望能将拉取和解析分开,然而我们也希望有这样一个方法,传入UIL和表单数据后,能直接返回解析好的对象数组。 所以就有了这样的一个在AsyncHttpClient框架基础上定制的框架。由我的小伙伴lwz大神,和打下手的MoblieXu完成。
项目中用的服务器地址,为自己的小项目中一处拉取JSon,请各位手下留情。
首先看一下,我们希望的结果一个方法传入参数就能返回解析好的对象数组:
public class MainActivity extends Activity { private TextView tv_showData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_showData =(TextView) findViewById(R.id.tv_showData); getWebData(); } private void getWebData() { GetJournalRequest getJournalRequest = new GetJournalRequest( getApplicationContext()); getJournalRequest.request(new ResponseParseHandler<List<Journal>>() { @Override public void onStart() { //mProgressBar.setVisibility(View.VISIBLE); } @Override public void onSuccess(List<Journal> result) { // } @Override public void onFailure(String error, String message) { AppContext.showToast(message + "--" + error); } }); } }
直接就能从onSuccess回调中获取数据,保证了方法的简洁;
GetJournalRequest.java public class GetJournalRequest extends AbsAsyncHttpRequest<JSONArray, List<Journal>> { public static final String KEY_PARAM_JOURNALS = "Journals"; public GetJournalRequest(Context context) { super(context); } @Override public String getAPI() { return API.GETJOURNAL_URL; } @Override public HttpMethod getHttpMethod() { return HttpMethod.GET; } @Override protected List<Journal> parseEntity(String parseData) throws JSONException { List<Journal> data = new ArrayList<Journal>(); JSONObject jsonObject = new JSONObject(parseData); JSONArray jsonArray = jsonObject.getJSONArray(KEY_PARAM_JOURNALS); GetJournalParser getJournalParser = new GetJournalParser(); for (int i = 0; i < jsonArray.length(); i++) { data.add(getJournalParser.parse(jsonArray.getJSONObject(i))); } return CollectionsUtil.isNullOrEmpty(data) ? new ArrayList<Journal>() : data; } }
将指向的UIL 和传递方式,还有解析Json都定义在这个类中,这个类继承之AbsAsyncHttpRequest
继承的时候设定了要返回的对象数组,
public abstract class AbsAsyncHttpRequest
public abstract class AbsAsyncHttpRequest<E, T> implements IAsyncHttpRequest<T> { public static final String JSON = "json"; private Context mContext; private HttpRequestParams mParams; private ResponseParseHandler<T> mHandler; private String mPrefName; private String mCacheKey; public AbsAsyncHttpRequest(Context context) { mContext = context; } public void setParams(HttpRequestParams params) { mParams = params; } public abstract String getAPI(); public abstract HttpMethod getHttpMethod(); public void request(final ResponseParseHandler<T> handler) { request(null, null, handler); } @Override public void request(String prefName, String cacheKey, final ResponseParseHandler<T> handler) { this.mPrefName = prefName; this.mCacheKey = cacheKey; mHandler = handler; mResponse.updatePreNames(mContext,mPrefName, mCacheKey); if (getHttpMethod() == HttpMethod.GET) { doGet(); } else { doPost(); } } private void doGet() { if (isParamsEmpty(mParams)) { RequestClient.get(getAPI(), mResponse); } else { RequestClient.get(getUrlWithParams(getAPI(), mParams), mResponse); } } private void doPost() { if (isParamsEmpty(mParams)) { RequestClient.post(getAPI(), mResponse); } else { RequestClient.post(getAPI(), mParams.toString(), mResponse); } } private boolean isParamsEmpty(HttpRequestParams params) { return params == null || params.isEmpty(); } private String getUrlWithParams(String url, HttpRequestParams params) { Set<String> keySet = params.keySet(); StringBuffer sb = new StringBuffer(); sb.append("?"); int i=0; for (String key : keySet) { i++; if(i==keySet.size()){ sb.append(key + "=" + params.get(key)); }else{ sb.append(key + "=" + params.get(key)+"&"); } } AppContext.showLog("GET方式URL" + url + sb.toString()); return url + sb.toString(); } private AsyncHttpResponse mResponse = new AsyncHttpResponse(mContext, mPrefName, mCacheKey, new LoadDataHandler() { @Override public void onStart() { // AppContext.showLog("onRequestStart"); mHandler.onStart(); } @Override public void onLoadCaches(String data) { // AppContext.showLog("onLoadCaches"); mHandler.onLoadCaches(parse(data)); } @Override public void onSuccess(String data) { // AppContext.showLog("成功获得Json数据" + data); mHandler.onSuccess(parse(data)); } @Override public void onFinished() { // AppContext.showLog("onFinished"); mHandler.onFinished(); } @Override public void onFailure(String error, String message) { AppContext.showLog(error + " " + message); mHandler.onFailure(error, message); } }); private T parse(String responseData) { JSONObject jsonData; try { jsonData = new JSONObject(responseData); BaseResponseParser<String> brp = new BaseResponseParser<String>( jsonData); if (brp.isSucceed()) { return parseEntity(brp.getData()); } else { mHandler.onFailure(brp.getErrorCode(), brp.getErrorMessage()); } } catch (JSONException e) { mHandler.onFailure("-1", e.getMessage()); } return null; } protected abstract T parseEntity(String parseData) throws JSONException; }
这里就是继承之AsyncHttpClient的基础类IAsyncHttpRequest,关键的是获取到数据之后将数据返回给了借口方法:
mHandler.onSuccess(parse(data));
private T parse(String responseData) { JSONObject jsonData; try { jsonData = new JSONObject(responseData); BaseResponseParser<String> brp = new BaseResponseParser<String>( jsonData); if (brp.isSucceed()) { return parseEntity(brp.getData()); } else { mHandler.onFailure(brp.getErrorCode(), brp.getErrorMessage()); } } catch (JSONException e) { mHandler.onFailure("-1", e.getMessage()); } return null; }
而parse方法,完成了json最基础的解析,比如说判断ret标识,如果数据没有错误的话,那么执行parseEntity
protected abstract T parseEntity(String parseData) throws JSONException;
这是一个抽象方法,具体的实现是在继承它的子类里面实现,所以这样也就实现了将解析和拉取分开,要解析成什么对象,由继承它的类决定,这个parseEntity就像一个钩子,最后又把解析好的对象数组返回回来,交给接口mHandler.onSuccess(parse(data));最有趣的是这个接口的实现也就是我们最外面调用的
@Override public void onSuccess(List<Journal> result) { // }
方法中省略了很多细节,仅仅是简单分析,有兴趣的小伙伴可以到github上拉下来,自己研究一下,有改进的地方,一定提出了。
github:https://github.com/xujinyang/AsyncHttpClientByLX