So,我们首先来规划一下网络模块的代码基本结构
网络模块的基本职责就是构建请求参数、请求服务器、响应服务器、加解密。UML图中,我们定义的了一个接口类,主要提供客户端访问服务器的预设的一些接口函数。
当MVP架构的Presenter指示器调用网络请求入口类(NetworkController)函数时,NetworkController 只需调用
NetworkInterface 中对应的接口函数,无需关心网络请求的具体类或细节。这样一定程度上做到了代码分离、解耦合,同时方便更换具体其他的网络请求具体实现类。如把VolleyHttpClient换成OKHttpClient即可。
/**
* 网络访问控制器
*
* @param <T>
*/
public class NetworkController implements NetworkInterface {
private static NetworkController mVolleyContrller;
private NetworkInterface mNetworkInterface;
private NetworkController(Context context) {
// 多态方便以后更换网络框架
mNetworkInterface = new VolleyHttpClient(context);
}
public static synchronized NetworkController getInstance(Context context) {
if (null == mVolleyContrller) {
// 单例,持有应用级别上下文,可以防止持有activity的上下文导致内存泄露
mVolleyContrller = new NetworkController(
context.getApplicationContext());
}
return mVolleyContrller;
}
@Override
public void requestCityList(Map<String, String> params, NetworkRequestListener callBack) {
mNetworkInterface.requestCityList(params, callBack);
}
@Override
public void requestCityWeatherDetailByIP(Map<String, String> params, NetworkRequestListener callBack) {
mNetworkInterface.requestCityWeatherDetailByIP(params, callBack);
}
@Override
public void requestCityWeatherDetailByCityID(Map<String, String> params, NetworkRequestListener callBack) {
mNetworkInterface.requestCityWeatherDetailByCityID(params,callBack);
}
}
/**
* 网络访问接口
*
*/
public interface NetworkInterface {
/**
* 请求城市列表
*
* @param params
* Map<String, String>
*
* @param callBack
* {@link NetworkRequestListener}
*/
public void requestCityList(Map<String, String> params, NetworkRequestListener callBack);
/**
* 通过IP请求天气详情
*
* @param params
* Map<String, String>
*
* @param callBack
* {@link NetworkRequestListener}
*/
public void requestCityWeatherDetailByIP(Map<String, String> params, NetworkRequestListener callBack);
/**
* 通过城市ID请求天气详情
*
* @param params
* Map<String, String>
*
* @param callBack
* {@link NetworkRequestListener}
*/
public void requestCityWeatherDetailByCityID(Map<String, String> params, NetworkRequestListener callBack);
}
/**
* Google 的Volley网络访问框架
*
*/
public class VolleyHttpClient implements NetworkInterface {
/** 请求队列 */
private RequestQueue queue;
private Context mContext;
public VolleyHttpClient(Context context) {
queue = Volley.newRequestQueue(context);
this.mContext = context;
}
/**
* put the request into RequestQueue
*
* @param
*/
private void addQueue(final String url, final NetworkRequestListener callBack) {
StringRequest request = new StringRequest(Request.Method.POST, url,
new Listener<String>() {
@Override
public void onResponse(String arg0) {
try {
//TODO:这里可以统一设置解密
// JSONObject obj = new JSONObject(arg0);
// String data = obj.optString("msg");
// data = NetworkUtility.decodResponseData(mContext, data);
if (null != callBack) {
callBack.response(arg0);
}
} catch (Exception e) {
if (null != callBack) {
callBack.error(0, e.getMessage());
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
if (null != callBack) {
callBack.error(0, parserNetError(url, arg0));
}
}
});
queue.add(request);
}
private String parserNetError(String url, VolleyError volleyerror) {
if (volleyerror instanceof ParseError) {
ParseError error = (ParseError) volleyerror;
if (!TextUtils.isEmpty(error.getMessage())) {
return error.getMessage();
} else {
return "获取数据失败";
}
} else if (volleyerror instanceof ServerError) {
return "服务器错误";
} else if (volleyerror instanceof NetworkError) {
return "网络不给力";
} else if (volleyerror instanceof TimeoutError) {
return "连接超时";
} else {
return "连接异常";
}
}
@Override
public void requestCityList(Map<String, String> params, NetworkRequestListener callBack) {
String url=API.getWeatherList+"?"+NetworkUtility.getUrlParams(mContext, params);
addQueue(url, callBack);
}
@Override
public void requestCityWeatherDetailByIP(Map<String, String> params, NetworkRequestListener callBack) {
String url=API.getWeatherDetailByIp+"?"+NetworkUtility.getUrlParams(mContext, params);
addQueue(url, callBack);
}
@Override
public void requestCityWeatherDetailByCityID(Map<String, String> params, NetworkRequestListener callBack) {
String url=API.getWeatherDetailByCityIndex+"?"+NetworkUtility.getUrlParams(mContext, params);
addQueue(url, callBack);
}
}
图片请求模块结构基本类似于网络部分,有兴趣的看官可以到GitHub上下载代码查阅。