作者:为谁落慕 | 来源:互联网 | 2023-02-06 10:53
以前听一个大神说过一句借用不知道哪位伟人的话:一个好的方法只有两三行,每个方法只专注一件事。本着这样的精神,我们在拉取网路数据的时候希望能将拉取和解析分开,然而我们也希望有这样一个方法,传入UIL和表
以前听一个大神说过一句借用不知道哪位伟人的话:一个好的方法只有两三行,每个方法只专注一件事。
本着这样的精神,我们在拉取网路数据的时候希望能将拉取和解析分开,然而我们也希望有这样一个方法,传入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>() {
@Override
public void onStart() {
//mProgressBar.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(List result) {
//
}
@Override
public void onFailure(String error, String message) {
AppContext.showToast(message + "--" + error);
}
});
}
}
直接就能从onSuccess回调中获取数据,保证了方法的简洁;
GetJournalRequest.java
public class GetJournalRequest extends
AbsAsyncHttpRequest> {
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 parseEntity(String parseData) throws JSONException {
List data = new ArrayList();
JSONObject jsOnObject= new JSONObject(parseData);
JSONArray jsOnArray= jsonObject.getJSONArray(KEY_PARAM_JOURNALS);
GetJournalParser getJournalParser = new GetJournalParser();
for (int i = 0; i data.add(getJournalParser.parse(jsonArray.getJSONObject(i)));
}
return CollectionsUtil.isNullOrEmpty(data) ? new ArrayList()
: data;
}
}
将指向的UIL 和传递方式,还有解析Json都定义在这个类中,这个类继承之
AbsAsyncHttpRequest>
继承的时候设定了要返回的对象数组,
public abstractclass AbsAsyncHttpRequest implements IAsyncHttpRequest 因为都是用泛型所以可以完成上面的设定。
public abstract class AbsAsyncHttpRequest implements IAsyncHttpRequest {
public static final String JSON = "json";
private Context mContext;
private HttpRequestParams mParams;
private ResponseParseHandler 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 handler) {
request(null, null, handler);
}
@Override
public void request(String prefName, String cacheKey,
final ResponseParseHandler 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 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 brp = new BaseResponseParser(
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 brp = new BaseResponseParser(
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 result) {
//
}
方法中省略了很多细节,仅仅是简单分析,有兴趣的小伙伴可以到github上拉下来,自己研究一下,有改进的地方,一定提出了。
github:https://github.com/xujinyang/AsyncHttpClientByLX
通过这样一个框架作为屌丝程序猿的我也能领会到编程的美和快乐,何况是大神们尼?