本文仅供自己回忆。以前自己写的下载都是用一个公共的utils进行下载,直到北京的同事用了这个方法写下载才发现自己好low,原谅我是一只很low的转行狗~记录自己的慢慢成长。
以前的做法太low 啊,就不说了,排版什么的去死吧,说说下载,一个app中很多地方都需要使用网络数据请求,如果不对它进行管理,那么非常不利于后期代码的维护,那么这里是怎么做的先看使用的时候怎么使用的,
/**
* 获取主题详情
*
* @param url
*/
private void getThemeDetails(final String url) {
RequestManager manager = RequestManager.getInstance(getApplicationContext());
Request request = RequestBuilder.getResourceRequest(url);
manager.requestData(request, new DataLoadListener() {
@Override
public void onSuccess(int statusCode, String content) {
Log.e(TAG, content);
ClassInfosDataBean classInfosDataBean = ClassInfosDataBean.parseJson(content);
specialList = classInfosDataBean.specialList;
// 默认是发现阶段的数据,id=50
for (int i = 0; i < specialList.size(); i++) {
SpecialsBean detailModel = specialList.get(i);
if (detailModel.name.equals("认知阶段")||detailModel.name.equals("感知阶段")) {
final String urll = detailModel.classesUrl;
runOnUiThread(new Runnable() {
public void run() {
getHongdongList(StringUtils.replaceString(urll));
}
});
}
}
}
@Override
public void onFailure(Throwable error, String errMsg) {
}
@Override
public void onCacheLoaded(String content) {
}
}, RequestManager.CACHE_TYPE_NOCACHE);
}
这里是一个简单的从一个url获取到json数据,在获取成功后将他解析成一个bean类,bean类中装载了json解析后的所有数据;
使用的时候很简单,一步一步来,要实现这个请求+解析+处理结果,bean类呢定义好json数据,这里选择的是原生解析;如下
public class ClassInfosDataBean extends CommenData {
private static final long serialVersionUID = 5443532814944804076L;
public int rltcode;
public String rltmsg;
public String object;
public ArrayList<SpecialsBean> specialList = new ArrayList<SpecialsBean>();;
public ArrayList<InfosBean> infosList = new ArrayList<InfosBean>();;
public static ClassInfosDataBean parseJson(String jsonObject){
ClassInfosDataBean classCourseDataBean = new ClassInfosDataBean();
try{
JSONTokener jsonParser = new JSONTokener(jsonObject);
JSONObject object = (JSONObject) jsonParser.nextValue();
classCourseDataBean.rltcode = JsonData.getInt(object, "rltcode", -1);
classCourseDataBean.rltmsg = JsonData.getString(object, "rltmsg", null);
JSONObject jsObj = object.getJSONObject("object");
if(classCourseDataBean.rltmsg.equals("success")){
JSONArray specialJsonList = new JSONArray();
specialJsonList = JsonData.getJSONArray(jsObj, "specials");
ArrayList<SpecialsBean> specialsBeansList = new ArrayList<SpecialsBean>();
if(specialJsonList != null){
for(int current= 0; current < specialJsonList.length(); current++){
JSONObject item = (JSONObject) specialJsonList.get(current);
SpecialsBean specialsBean = new SpecialsBean();
specialsBean.classesId = JsonData.getString(item, "id", null);
specialsBean.name = JsonData.getString(item, "name", null);
specialsBean.classesUrl = JsonData.getString(item, "url", null);
specialsBean.introduction = JsonData.getString(item, "introduction", null);
specialsBean.releaseData = JsonData.getString(item, "releaseData", null);
specialsBeansList.add(specialsBean);
}
}
classCourseDataBean.specialList = specialsBeansList;
JSONArray infosJsonList = new JSONArray();
infosJsonList = JsonData.getJSONArray(jsObj, "infos");
ArrayList<InfosBean> infosBeansList = new ArrayList<InfosBean>();
if(infosJsonList != null){
for(int current= 0; current < infosJsonList.length(); current++){
JSONObject item = (JSONObject) infosJsonList.get(current);
InfosBean infosBean = new InfosBean();
infosBean.html = JsonData.getString(item, "html", null);
infosBean.img = JsonData.getString(item, "img", null);
infosBean.infosIntroduction = JsonData.getString(item, "introduction", null);
infosBean.title = JsonData.getString(item, "title", null);
infosBeansList.add(infosBean);
}
}
classCourseDataBean.infosList = infosBeansList;
}
}catch(Exception e){
e.printStackTrace();
}
return classCourseDataBean;
}
}
在这里将json数据封装好,并且提供一个解析的方法对返回成功的数据进行解析;
再看下怎么实现根据一个url请求到数据
manger只需要一个,调用getinstence()方法获得一个manger的对象
public static RequestManager getInstance(Context cxt) {
if (instance == null)
instance = new RequestManager(cxt);
return instance;
}
而请求的时候调用,传入一个request对象,一个监听器(成功做什么,失败做什么),第三个参数是缓存的类型
public void requestData(Request request, DataLoadListener dataListener, int cacheType) {
requestData(request, dataListener, cacheType, DEFAULT_REQ_TIME_SPACE);
}
分两步走,第一步看下request中他做了什么,第二步看下
DataLoadListener 接口中他回调方法怎么用的(),先看了下
requestData,最终调用了这个方法,看得好累,干脆贴上去,以后看,这里面应该是实现了下载的逻辑
private void requestDataBasic(Request request,
final DataLoadListener dataListener, final int cacheType, int cacheTimeoutSeconds) {
int reqType = request.reqType;
final String url = request.url;
final String bodyContent = request.body;
final int urlHash = getUrlHash(request);
final String bodyHash = getBodyHash(request);
String selection = getCacheSelection(request);
String paramedUrl = getParamedUrl(request, null);
ZYLog.d(TAG, "RequestData, url: " + paramedUrl + ", bodyContent: " + bodyContent + ", loadCache: " + cacheType + ", selection: " + selection);
final String cacheKey = urlHash + "_" + bodyHash;
long cacheTime = 0;
String cacheResult = null;
long cacheId = -1;
boolean hasCache = false;
// 从缓存中取数据
Cursor cursor = mContext.getContentResolver().query(CacheProvider.CONTENT_URI, mProjection, selection, null, null);
if (cursor != null && cursor.moveToFirst()) {
cacheTime = cursor.getLong(cursor.getColumnIndex(CacheProvider.Columns.time));
cacheResult = cursor.getString(cursor.getColumnIndex(CacheProvider.Columns.responseStr));
cacheId = cursor.getLong(cursor.getColumnIndex(CacheProvider.Columns._ID));
hasCache = true;
}
if (cursor != null) cursor.close();
dataListener.setId(cacheId);
dataListener.setCacheTime(cacheTime);
if (hasCache) {
if (cacheType == CACHE_TYPE_NORMAL) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
if (System.currentTimeMillis() - cacheTime < cacheTimeoutSeconds) return;
} else if (cacheType == CACHE_TYPE_IGNORE_TIME) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
} else if (cacheType == CACHE_TYPE_FIRST_REQUEST) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
if (mCacheTimes.get(cacheKey) != null && mCacheTimes.get(cacheKey) > 0) {
ZYLog.d(TAG, "This request has been responded from server, do not send the request again");
return;
}
} else if (cacheType == CACHE_TYPE_CACHEONLY) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
return;
}
}
if (cacheType == CACHE_TYPE_CACHEONLY) return;
if (cacheType == CACHE_TYPE_NOCACHE) {
dataListener.setShouldSaveCache(false);
}
final String cacheContent = cacheResult;
final boolean isInCache = hasCache;
AsyncHttpResponseHandler responseHandler = new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, String content) {
// if (!dataListener.onPreCheck(content)) {
// dataListener.onFailure(null, content);
// return;
// }
dataListener.onSuccess(statusCode, content);
if(!dataListener.isShouldSaveCache()) {
ZYLog.d(TAG, "Return result from server without saving in cache, url: " + url + ", cacheType: " + cacheType + ", result: " + content);
return;
}
ZYLog.d(TAG, "Return result from server and save in cache, url: " + url + ", cacheType: " + cacheType + ", result: " + content);
long curTime = System.currentTimeMillis();
mCacheTimes.put(cacheKey, curTime);
ContentValues values = new ContentValues();
values.put(CacheProvider.Columns.requestStr, bodyHash);
values.put(CacheProvider.Columns.requestType, urlHash);
values.put(CacheProvider.Columns.responseStr, content);
values.put(CacheProvider.Columns.time, curTime);
if (dataListener.getId() == -1) {
mContext.getContentResolver().insert(CacheProvider.CONTENT_URI, values);
} else {
mContext.getContentResolver().update(
ContentUris.withAppendedId(
CacheProvider.CONTENT_URI,
dataListener.getId()), values, null, null);
}
}
@Override
public void onFailure(Throwable error, String content) {
ZYLog.d(TAG, "Request failed, url: " + url + ", error: " + error);
Map<String,String> param = new HashMap<String, String>();
param.put(url, error.getMessage());
dataListener.onFailure(error, content);
if (isInCache && cacheType == CACHE_TYPE_NETWORK_FIRST) {
dataListener.onCacheLoaded(cacheContent);
}
}
};
// 网络不可用,不发送网络请求
if (!CheckNetWorkStatus.isNetworkAvailable(mContext)) {
dataListener.onFailure(new HttpResponseException(9999, "Network not avilable!"), "Network not avilable!");
if (hasCache && cacheType == CACHE_TYPE_NETWORK_FIRST) {
dataListener.onCacheLoaded(cacheContent);
}
return;
}
// if (reqType >= REQ_TYPE_CYAN_LOADTOPIC && reqType <= REQ_TYPE_CYAN_COUNTS) {
CyanClient.getInstance().requestData(reqType, bodyContent, responseHandler);
// } else if (reqType >= REQ_TYPE_JIONG_SECTIONS) {
// WebService.requestGet(url, responseHandler);
// } else {
WebService.request(paramedUrl, bodyContent, responseHandler, request.reqMethod);
// }
}
算了算了,还是看下这个传入的三个参数吧,第三个参数是一个标记,第一个参数request容我去找找
/**获取资源列表*/
public static Request getResourceRequest(String url) {
Request request = new Request();
request.url = BASE_URL + url;
request.reqMethod = Request.REQ_METHOD_GET;
return request;
}
在这里,传递进去了一个url,根据使用的地方都给他赋值好一个完整的url,
request.reqMethod request.url两个的赋值吧;再看了下,这些都是get请求,reqmethod就选了
REQ_METHOD_GET,看看好像是那么回事。<pre name="code" class="html">}
/**获取资源列表*/
public static Request getResourceRequest(String url) {
Request request = new Request();
request.url = BASE_URL + url;
request.reqMethod = Request.REQ_METHOD_GET;
return request;
}
/**获取版本升级*/
public static Request getVersionUpdateRequest() {
Request request = new Request();
request.url = BASE_URL + "/s.py?pg=c&gd=4&cd=242";
request.reqMethod = Request.REQ_METHOD_GET;
return request;
}
/**获取资源列表*/
public static Request getResourceList(String url) {
Request request = new Request();
request.url = BASE_URL + url;
request.reqMethod = Request.REQ_METHOD_GET;
return request;
}
/**获取AR图库列表*/
public static Request getArResourceRequest() {
Request request = new Request();
request.url = BASE_URL + "/pps/s.py?pg=c&gd=4&cd=66";
request.reqMethod = Request.REQ_METHOD_GET;
return request;
}
从这里可以看出来这个实际上就是对url进行拼接。
而关键的第二个监听是怎么实现的,让我再好好找找。
if (hasCache) {
if (cacheType == CACHE_TYPE_NORMAL) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
if (System.currentTimeMillis() - cacheTime < cacheTimeoutSeconds) return;
} else if (cacheType == CACHE_TYPE_IGNORE_TIME) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
<span style="color:#ff0000;"> dataListener.onCacheLoaded(cacheResult);</span>
} else if (cacheType == CACHE_TYPE_FIRST_REQUEST) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
<span style="color:#ff0000;"> dataListener.onCacheLoaded(cacheResult);</span>
if (mCacheTimes.get(cacheKey) != null && mCacheTimes.get(cacheKey) > 0) {
ZYLog.d(TAG, "This request has been responded from server, do not send the request again");
return;
}
} else if (cacheType == CACHE_TYPE_CACHEONLY) {
ZYLog.d(TAG, "Return result from cache, url: " + url + ", cacheType: " + cacheType + ", result: " + cacheResult);
dataListener.onCacheLoaded(cacheResult);
return;
}
}
原来在requestDataBasic中使用的。暂时分析到这里,大概懂了,但是要我写一个感觉还是好难啊,一点都不简单