Http网络请求框架
最近在做一款天气预报的App,由于会接触到网络,所以在网上看了好多的资料,先开始根本没有想到用网络框架什么的,听到框架神马的好像都十分高达上的,跟自己都没什么关系,在App开发的过程中一次断网调试的时候崩掉了,让我觉得自己写的那个逻辑形式很不稳定,于是上网到处搜罗 ,发现了一个博主的框架,分析了一段时间之后貌似懂了些,用起来还不错,拿上来和大家分享哈~
感谢
linxcool
大神的框架 .
![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
整个框架里面有5个类:
一.HttpListener.java Http监听接口
二.Update.java Observer接口,在这个框架中运用到了观察者模式
三.ActionService.java 动作服务类,用来获得网络请求相应的动作实例(BaseAction)
四.HttpUtil.java 自定义的Http工具类,里面写有关于网络请求和处理请求数据的各种函数.
五.BaseAction.java 基础动作类,这个是框架中最主要的类,里面持有HttpUtil类的一个实例,用于调用各种请求函数.
大概介绍了一哈整个框架的结构后,应该有所了解了,下面开始按照上面的顺序开始详细的介绍.....
,主要还是在注释里面
![奋斗](http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif)
这个就是 HttpListener.java接口,里面有两个函数等待着实现,分别对应着请求完成和请求失败.....
HttpListener.java
/**
* Http监听接口
*
*/
public interface HttpListener {
/**
* 完成网络请求
* @param response
*/
public void onComplete(String response);
/**
* 网络请求失败
*/
public void onError();
}
第二个介绍的就是Update.java Observer接口,在需要被提醒(观察着模式)的类中继承Observer,写入执行代码就可以了.
/**
* Observer接口
* 这个类一般在UI的类中继承Observer后写入
* 在框架中请求完成或者超时后都会提醒所有注册了的观察着
* 到时候就可以很方便的对网络请求做出各种UI上的响应
*/
@Override
public void update(Observable observable, Object data) {
int code=(Integer) data;
switch (code) {
case BaseAction.SUCCESS:
/**
* 这个里面放入网络请求完成后
* 需要做的事情
*/
break;
case BaseAction.EXCEPTION:
/**
* 这个里面放入网络出现Exception后
* 需要做的事情
*/
break;
case BaseAction.ERROR:
/**
* 这个里面放入网络Error后
* 需要做的事情
*/
break;
}
}
第三个是ActionService.java
/**
* 动作服务类
*/
import android.app.Activity;
public class ActionService {
private Activity activity;
public ActionService(Activity activity){
this.activity=activity;
}
/**
* 获取Context对象
* @return
*/
public Activity getActivity() {
return activity;
}
}
第四个类就是HttpUtil.java
/**
* HTTP工具类
* 在BaseAction中持有一个此类的实例
* 主要是用于发送请求和接收请求的数据
*/
public class HttpUtil {
private Context context;
/**HTTP常量-GET请求*/
public static final int HTTP_METHOD_GET=1;
/**HTTP常量-POST请求*/
public static final int HTTP_METHOD_POST=2;
/**HTTP常量-请求限制时间*/
public static final int HTTP_REQ_LIMIT_TIME=15*1000;
/**HTTP常量-响应限制时间*/
public static final int HTTP_RES_LIMIT_TIME=25*1000;
//返回码
public static final int RES_CODE_SUCCESS=200;
public static final int RES_CODE_ERROR=1;
public static final int RES_CODE_FAIL=2;
private HttpClient client;
private HttpResponse response;
public HttpUtil(Context context) {
this.context=context;
}
/**
* 给Http的请求设置了请求限时
* 编码的格式和版本
* @return
*/
public HttpClient createHttpClient(){
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_REQ_LIMIT_TIME);
HttpConnectionParams.setSoTimeout(params,HTTP_RES_LIMIT_TIME);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
return new DefaultHttpClient(params);
}
/**
* 根据传进来的参数method
* 对应的生成get请求
* 或者是post请求
*
* @param url
* @param method
* @return
*/
public HttpUriRequest createHttpRequest(String url,int method){
HttpUriRequest request=null;
if(method == HTTP_METHOD_GET){
request=new HttpGet(url);
}else{
request=new HttpPost(url);
}
//关闭 100-Continue 询问
request.getParams().setBooleanParameter(
CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
return request;
}
/**
* openUrl函数
* 发送http请求到网络服务器
* 用response来存放返回的数据
*
* 里面调用了createHttpClient函数(也就是上面的那个函数)
* 来生成相应的请求
*
* @param request
* @return
*/
public boolean openUrl(HttpUriRequest request){
client=createHttpClient();
try {
response=client.execute(request);
return true;
} catch (IOException e) {
e.printStackTrace();
response=null;
}
return false;
}
/**
* 针对网络请求返回的那个HttpResponse实例对象(resopnse)
* 进行一系列的解析操作
* 利用输入输出流来解析出需要的result
* @return
*/
public String getHttpResponse(){
String result = null;
try {
if(response==null)return null;
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
ByteArrayOutputStream content = new ByteArrayOutputStream();
int readBytes = 0;
byte[] sBuffer = new byte[512];
while ((readBytes = inputStream.read(sBuffer)) != -1)
content.write(sBuffer, 0, readBytes);
result = new String(content.toByteArray());
result=URLDecoder.decode(result, "UTF-8");
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(client!=null)
client.getConnectionManager().shutdown();
}
return result;
}
/**
* 说多了就这么一个函数
* 在其他的类中实例化HttpUtil类后
* 只需要调用一个request函数即可
* 此函数中调用了openUrl函数
* 接着就挨个调用了上面的一系列函数来达到网络请求的目的
*
* @param url
* @param request
* @param listerner
*/
public void request(
final String url,final HttpUriRequest request,final HttpListener listerner) {
new Thread() {
@Override
public void run() {
boolean ret = openUrl(request);
if(!ret){
listerner.onError();
return;
}
listerner.onComplete(getHttpResponse());
}
}.start();
}
}
第五个类是最主要的,
/**
* 基础动作类
* 主要的功能都在这个类中实现
*
* 执行请求动作
* 提醒观察者
* 解析数据
*/
public abstract class BaseAction extends Observable implements HttpListener,Runnable{
private static final String TAG="BaseAction";
//动作ID列表 根据实际情况更改
public static final int ACTION_ID_INTRO=1;
public static final int ACTION_ID_SHARE=2;
//响应状态结果
public static final int SUCCESS=0;
public static final int ERROR=1;
public static final int EXCEPTION=2;
//上下文对象
protected Context context;
protected ActionService actionService;
//动作信息列表
protected int actionId;
protected HttpUtil httpUtil;
protected int method;
protected String content;
//响应信息
protected String response;
protected String resMsg;
public String getResMsg() {
return resMsg;
}
/**
* 构造函数
* 初始化各种数据
*
* @param actionService
* @param actionId
*/
public BaseAction(ActionService actionService,int actionId){
this.actionService=actionService;
this.context=actionService.getActivity();
this.actionId=actionId;
httpUtil=new HttpUtil(context);
method=HttpUtil.HTTP_METHOD_POST;
}
/**
* 执行网络请求动作
* 只需要调用这么一个函数
* 就能完成从请求到数据的返回所有工作
* 包括中间出现了断网等各种现象都不会崩掉
*
* 调用了一个函数doRequest(),这个函数会在下面讲到
*/
public void actionStart(){
try {
doRequest(
httpUtil.REQUEST_HOST+getURL(),
content);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
protected void putBasicData(JSONObject jsonObj) throws JSONException{
}
public abstract void putData(Object... datas);
/**
*调用了HttpUtil中的request方法
*
* @param url
* @param content
* @throws UnsupportedEncodingException
*/
public void doRequest(String url,String content) throws UnsupportedEncodingException{
HttpUriRequest request=httpUtil.createHttpRequest(url, method);
if(content != null){
HttpPost post=(HttpPost) request;
post.setEntity(new StringEntity(content));
}
httpUtil.request(url, request, this);
}
/**
* 在doRequest的请求结束之后
* 就会自动的调用这个函数
* 里面的这个response就是我们需要的结果
*
* 接着就会调用下下下下面的run()
* 根据返回的结果来提示观察着该做些什么
* @param response
*/
@Override
public void onComplete(String response) {
this.response=response;
((Activity)context).runOnUiThread(this);
}
@Override
public void onError() {
response=null;
((Activity)context).runOnUiThread(this);
}
private String getURL(){
switch (actionId) {
case ACTION_ID_INTRO:
return "login";
}
}
/**
*根据不同的信息来提示实现并注册了的Observer
* 做出不同的响应动作
*/
@Override
public void run() {
setChanged();
if(response==null){
notifyObservers(ERROR);
return;
}
try {
JSONObject obj = new JSONObject(response);
int code=obj.getInt("code");
if(code==HttpUtil.RES_CODE_SUCCESS){
onResSuccess(obj);
notifyObservers(SUCCESS);
}else{
resMsg=obj.getString("msg");
notifyObservers(EXCEPTION);
}
} catch (Exception e) {
e.printStackTrace();
resMsg="数据解析错误";
notifyObservers(ERROR);
}
}
/**
* 网络请求成功后将执行该方法
* @param obj
* @throws Exception
*/
public abstract void onResSuccess(JSONObject obj) throws Exception;
}
注释里面解释的应该够清楚了把,如果还有什么不懂得可以Q我2319821734,也可以给我留言的.....还有再次谢谢代码的作者linxcool~~~~,这个框架也在小达快做完了的一个天气App里面,在后面有时间我会整理下,把整个App的开发流程双手奉上的.今天就到这里咯,88~~~~~