网络框架的使用

来源:互联网 发布:mac蓝光刻录软件 编辑:程序博客网 时间:2024/05/21 23:00

为什么会突然想写这个呢,一个是太长时间没碰博客了,忙着做项目,另一个是接手了几个烂项目,才知道这东西又多么重要!!被坑的

言归正传,做一个网络框架,需要做到什么呢?

层次分明,这里我归类为三层

1)底层网络调用,所有的网络都会经过底层这里,方便做统一的管理   BaseHttpRequest

(家里总要有一个管事的)

2)中间层封装,为了隔离代码与底层,并且方便开发者处理网络接口,这里统一将网络接口封装到一起,方便看,方便改    NetRequest

                

3)应用层调用,好的接口调用在应用层应该就只有一行代码,这样不会有过多的冗余的东西要处理。


                                                                                    层思想很丰满,现实很骨感,素不素感觉还是无从下手!!!

1.先选择网络框架(其实你选啥都一样,我这种设计所有网络框架通吃!!),这里选择afinal作为示例。

2.准备好jar包丢到libs目录下,网上随便下一个就好了,afinal_0.5.1_bin.jar

3.创建BaseHttpRequest.class

1 )先写构造函数,无论何时都会需要上下文滴,并初始化fh

public BaseHttpRequest(Context context) {    this.context = context;    fh = getFh();}public FinalHttp getFh() {    if (fh == null) {        fh = new FinalHttp();        fh.configTimeout(30 * 1000); // 设置超时连接 10秒    }    return fh;}

2)考虑到用get请求选择太少了,毕竟不安全,这里直接用POST,需要用GET自己稍微改一下就好了。

做这一步先你要知道一个东西,我们网络请求网络接口的时候,一般服务器域名是不会变的,变的只是不同接口调用不同的service跟传不同的params参数

所以,调用post请求之前,先把url的各部分传递过来,组装成url后并打印,方便调试。

serviceAction:service的访问路径

requestId:简单的标示,这样的话在同一个页面调用多个网络接口时候,可以区分,这个跟startActivityforResult时候多传个参数是同个道理。

url:服务器地址

params:接口封装好的参数,是键值对格式

ifShosDialog:考虑网络请求时候一般都需要考虑弱网情况,所以这里加个字段判断是否需要显示加载框,一定不要写死,因为实际应用中往往会有需求是偷偷调接口,那时候就不要加载框了~createLoadingDialog我就不贴代码了,你根据你喜欢自己画吧。

这里需要注意一点:不同公司后台肯定要有自己的规范,所以这里要提前约定好,网络请求成功之后返回统一的格式是什么,这里就跟后台商量好了,如果成功就会返回succ,数据统一丢到data里面,失败就返回error_msg

{"rsp_code":"succ","data":{"version_code":57,"version_name"}

public void doPostRquest(String serviceAction, final int requestId, String url, AjaxParams params,                         final boolean ifShowDialog) {    Log.i("zyl", "requestURL:" + url + serviceAction + "?" + params.toString());    fh.post(url + serviceAction, params, ajaxcallback = new AjaxCallBack<Object>() {        @Override        public void onStart() {            super.onStart();            if (ifShowDialog) {                if (loadingDialog == null) {                    createLoadingDialog(context, "数据加载中...");                }                loadingDialog.show();            }        }        @Override        public void onSuccess(Object t) {            super.onSuccess(t);            loadingDialog.dismiss();            String result = t.toString();            try {                JSONObject json = new JSONObject(result);                String rspCode = json.getString("rsp_code");                Log.v("zyl", "onSuccess:" + result);                if (rspCode.equals("succ")) {                    String data = json.getString("data");                    ResultEntity resultEntity = new ResultEntity("", data, requestId);                    Message message = new Message();                    message.what = HANDLER_WHAT_SUCESS;                    message.obj = resultEntity;                    baseHandler.sendMessage(message);                } else {                    String msg = json.getString("error_msg");                    if (msg.contains("token")) {                      //token失效重新登录这里严谨一点应该返回固定的code,收到这信号就去重新登录就对了。                        baseHandler.sendEmptyMessageDelayed(EXIT, 0);                    } else {                        Message message = new Message();                        message.what = HANDLER_WHAT_FAIL;                        ResultEntity resultEntity = new ResultEntity(msg, "", requestId);                        message.obj = resultEntity;                        baseHandler.sendMessage(message);                    }                }            } catch (JSONException e) {                e.printStackTrace();            }        }        /**         * 处理请求失败的回调函数         */        @Override        public void onFailure(Throwable t, int errorNo, String strMsg) {            Log.i("zyl", "onAfinalFail:" + strMsg);            if (loadingDialog != null) {                loadingDialog.dismiss();            }            super.onFailure(t, errorNo, strMsg);            Message message = new Message();            message.what = HANDLER_WHAT_NET;            ResultEntity resultEntity = new ResultEntity("", "", requestId);            message.obj = resultEntity;            baseHandler.sendMessage(message);        }    });}


就是这么简单!!网络请求成功之后拿到了data,然后将数据封装到下面的实体bean里面,成功的时候一般我关心data,失败的时候我们关心失败的原因msg.   

public class ResultEntity {    String msg;             //失败原因    String data;            //成功返回数据    int requestId;          //请求的标示,区分不同的网络请求    public ResultEntity(String msg, String data, int requestId) {        this.msg = msg;        this.data = data;        this.requestId = requestId;    }}
ok,到这里我们已经从onSuccess拿到接口调用成功的数据或者被拒绝原因,从onFailure拿到网络调用失败的原因

那么,怎么传回给NetRequest,再传回应用层呢??????????

写个回调接口:

public interface IOnHttpListener {    /**     * 网络请求失败(没有网络或连接服务器原因)     *     * @param requestId     */    void onAfinalFail(int requestId);    /**     * 网络请求成功,拿到想要的数据result,一般msg用不上。     *     * @param requestId     * @param result     */    void onExecuteSuccess(int requestId, String result, String msg);    /**网络通的,但请求方式有误或者数据有误失败;     * 返回失败信息     *     * @param requestId     *            请求id     * @param result     *            失败提示     */    void onExecuteFail(int requestId, String msg);}

回调用法就很简单了吧。在Activity实现这个接口,重写下面三个方法

public class MainActivity extends BaseActivity implements IOnHttpListener {    private NetRequest netRequest;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(com.netframework.R.layout.activity_main);        netRequest = new NetRequest(this);        netRequest.requestCheckVersion(1,true);    }    @Override    public void onAfinalFail(int requestId) {        Log.v("zyl","onAfinalFail requestId :"+requestId);    }    @Override    public void onExecuteSuccess(int requestId, String result, String msg) {    }    @Override    public void onExecuteFail(int requestId, String msg) {    }}
到这里可能有人会说我骗你,只写一行代码就能调用接口???

看来我只能放绝招了,修改为一下:

new NetReuest(this).requestCheckVersion(1,true);

哈哈。开玩笑,实际上还是不建议这样写,还是参考上面的写法吧。这样同个页面NetRequest不用重复new

有的同学有点懵逼。底层BaseHttpRequest 写好了,应用层调用代码也写好了,那么中间层NetRequest该怎么写呢?

接下就让我们来走进科学。。。


先看构造:

/** * 给Activity调用 * * @param context */public NetRequest(Context context) {    this.context = context;    this.listener = (IOnHttpListener) context;    request = new BaseHttpRequest(context);    request.setHttpListener(listener);}/** * 给Fragment调用 * * @param listener * @param context */public NetRequest(IOnHttpListener listener, Context context) {    this.context = context;    request = new BaseHttpRequest(context);    request.setHttpListener(listener);}

能看懂为什么Fragment调用要多传个参数么,因为Activity本身就继承Context,所以直接就是实现我们接口的那个婊子了啊 。

这里补充一下BaseHttpRequest的一个方法,方便将示例对象从Activity->NetRequest->BaseHttpRequest

public void setHttpListener(IOnHttpListener httpListener) {    this.httpListener = httpListener;}

BaseHttpRequest调用接口之后拿到状态,我们就可以通过这个IOnHttpListener传回去。是不是觉得一切都在套路中。。冥冥之中自由安排。

 * 把服务器原始结果进行处理 */private Handler baseHandler = new Handler() {    public void handleMessage(Message msg) {        ResultEntity result = (ResultEntity) msg.obj;        switch (msg.what) {            case HANDLER_WHAT_SUCESS:                if (httpListener != null)                    httpListener.onExecuteSuccess(result.requestId, result.data, result.msg);                break;            case HANDLER_WHAT_FAIL:                if (httpListener != null)                    httpListener.onExecuteFail(result.requestId, result.msg);                break;            case HANDLER_WHAT_NET:                if (httpListener != null)                    httpListener.onAfinalFail(result.requestId);                break;            case EXIT:                break;            default:                break;        }    }};

最后的最后,我回到中间层补充完最后那段代码,

netRequest.requestCheckVersion(1,true);

1.这个接口很简单,我需要参数就是包名而已

2.requestData 传递serviceAction,requestId,ifShowDialog,params

3.requestData则调用网络基类中的那个request

private BaseHttpRequest request;    //网络请求的基类

/** * @param requestId    网络请求id,用于区分同个页面的不同网络请求 * @param ifShowDialog 是否显示提示框 */public void requestData(String serviceAction, int requestId, boolean ifShowDialog, AjaxParams params) {    request.requestData(serviceAction, requestId, ifShowDialog, params);}


结束!!!!!!!!!!终于写完了,到了这里,有的同学会说,不是说所有网络框架通吃么,那么怎么换呢?你要做的只是把底层那个BaseHttpRequst的post请求方式改为你那个网络框架的post请求方式,其他全都不用变。。毕竟思想是一样的,大道至简!!






1 0
原创粉丝点击