美文网首页
简单的网络框架搭建

简单的网络框架搭建

作者: GOOD_end | 来源:发表于2015-11-09 20:33 被阅读158次

    一、概述

    在我们app的开发中,经常会使用一些网络请求,一般我们都会去选择网络上比较的流行的网络框架,如: async_http_client、volley和okhttp等。 通过粗略的研究这么几个网络请求框架。发现他们在网络请求上的封装都差不多. 这样我萌发出了自己也写一个简单的网络请求框架的想法. 废话不多说,来我们一起分析下,一般的框架都有哪些部分组成。

    二、简单框架的分析

    一般的框架给我们提供的api是非常简单的,一般都有url、params和responseListener等主要的几个参数。让我们不比去关注它是否是在主线程中运行、线程池等问题。其实真正的联网操作肯定是在异步线程中,返回的结果通过回调机制返回给主线程。

    三、框架的基本组成

    这样我们就可以看出有一个对请求进行配置的类(RequestConfig),里面包含了请求的路径、参数、请求超时时间等. 还有处理真正联网操作的类(MyHttpClient),主要采用了AsyncTask+HttpClient来处理联网操作。还有就是将得到的结果通过回调返回回去(ResponseListener),接下来就是我们提供给别人用的api接口方法的类(RequestHandler)。

    RequestConfig.java

     /** 
    * @className:RequestConfig.java
    * @classDescription: 请求的相关配置类
    */
     public class RequestConfig  {
      
     public String requestUrl;   //请求路径
    
     public Map<String, String> paramsMap;  //请求参数
    
     public List<NameValuePair> fileParams; //文件参数
     
     public int timeOut; //请求超时时间
     }
    

    MyHttpClient.java

    这是从服务器端请求返回的数据,由于代码太多,只贴出了部分代码,其中 MyHttpClient.getHttpClient(config)方法是对httpclient做了一些处理,包含获取数据buffersize大小和超时时间的设置。

     /**
      * 返回结果
      * @param config
      * @return
      * @throws Exception
      */
     private static String getResponseFromServer(RequestConfig config, String requestMethod) throws Exception {
         String response = "";
         
         HttpClient client = MyHttpClient.getHttpClient(config);
         List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
         HttpPost httpPost = null;
         HttpGet httpGet = null;
         
         if (config.requestUrl.startsWith("http://") || config.requestUrl.startsWith("https://")) {
             //处理普通请求的参数
             if (config.paramsMap != null) {
             Iterator<String> v1 = config.paramsMap.keySet().iterator();
             while (v1.hasNext()) {
                 String key = v1.next();
                 if (config.paramsMap.get(key) == null) {
                     continue ;
                 }
                 params.add(new BasicNameValuePair(key, config.paramsMap.get(key).toString()));
             }
           }  
             HttpResponse v2 = null;
             if ("GET".equals(requestMethod)) {
                 httpGet = new HttpGet(config.requestUrl);
                  v2 = client.execute((HttpUriRequest) httpGet);
             } else {
                 httpPost = new HttpPost(config.requestUrl);
                 httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));  
                 v2 = client.execute((HttpUriRequest) httpPost);
             }
            
             //记录返回的头文件
             MyHttpClient.logHeaders(v2);  
             if (v2.getStatusLine().getStatusCode() == 200) {
                 response = EntityUtils.toString(v2.getEntity(), "UTF-8");
             }
             LogUtils.e(TAG, "stat code:" + String.valueOf(v2.getStatusLine().getStatusCode()));
             httpPost.abort();
         } else {
             return "";
         }
             
         return response;
     }
    

    这里采用了AsyncTask对联网操作进行了处理,如果期间出现了异常将会在处理一次,这个在volley框架中也可以看得到。最后请求结果通过responseListener中返回。这里结果进行了封装listener.onResponse(CommonResult.resultWithData(result), result) 根据返回的json数据会初步解析下,得到结果的状态。

    /**
      * post的请求
      * @param config
      */
     public static void post(final RequestConfig config, final ResponseListener listener){
         LogUtils.e(TAG, "请求路径 : " + config.requestUrl);
         
         AsyncTask  asyncTask = new AsyncTask<Object, Integer, String>(){
    
            @Override
            protected String doInBackground(Object... params) {
                String result = null;
                  try {
                        result = MyHttpClient.getResponseFromServer(config, "POST");
                } catch (Exception e) {
                    try {
                        result = MyHttpClient.getResponseFromServer(config, "POST");  // 错误了 在请求一次
                    } catch (Exception e1) {
                        e1.printStackTrace();
                        // 发生错误时, 将错误信息返回
                        if (listener != null) {
                            listener.onResponse(CommonResult.resultWithData(ResultCode.RESULT_CODE_FAILURE, e1.toString()), null);
                        }
                    }
                }
                return result;
            }
             
            protected void onPostExecute(String result) {
                LogUtils.d(TAG, "返回的结果 : " + result);
                if (listener != null) {
                    if (!TextUtils.isEmpty(result)) {
                    listener.onResponse(CommonResult.resultWithData(result), result);
                    }
                }
            };
            
         };
         asyncTask.executeOnExecutor(MyHttpClient.THREAD_POOL_EXECUTOR, 0);
     }
    

    ResponseListener.java

    这里只有一个接口方法,因为我在CommonResult中做了处理,错误的结果也封装在一起了,得到结果时,需要判断commonResult的状态。然后做相应的数据处理,data为返回的json数据。
    public interface ResponseListener {
    void onResponse(CommonResult commonResult, String data);
    }

    RequestHandler.java

    提供给别人使用的api接口,根据不同的情况调用不同的方法。

    /**
     * post的请求,多参数下的使用方式 
     * @param context
     * @param url
     * @param params
     * @param listener
     */
    public static void post(Context context, String url, Map params, int requestTimeout, ResponseListener listener) {
        //构建请求配置参数
        RequestConfig config = new RequestConfig(); 
        config.requestUrl = url;
        config.paramsMap = params;
        config.timeOut = requestTimeout;
        if (HttpUtils.checkedNetwork(context)) {  //先判断有没有网络
            MyHttpClient.post(config, listener);
        } else {
            if (listener != null) {
                listener.onResponse(CommonResult.resultWithData(ResultCode.RESULT_CODE_NETWORK_FAILURE, context.getResources().getString(R.string.network_error)), null);
            }
        }
    }
    
    /**
      * 
      * @param context
      * @param url
      * @param listener
      */
     public static void post(Context context, String url, ResponseListener listener) {
         RequestHanler.post(context, url, null, 0, listener);
      }
    
    /**
      * 
      * @param context
      * @param url
      * @param params
      * @param listener
      */
    public static void post(Context context, String url, Map params, ResponseListener listener) {
       RequestHanler.post(context, url, params, 0, listener);
    }
    

    总结

    这里我只是简单的写了个网络请求的demo,其中大部分代码还没有贴上来,其中还有上传下载的部分,我知道这个连基本的框架各种难点都没有涉及到,我主要是写框架的大概思想。算是自己的一个简单的总结吧!

    相关文章

      网友评论

          本文标题:简单的网络框架搭建

          本文链接:https://www.haomeiwen.com/subject/mjjthttx.html