OkHttp的二次封装

来源:互联网 发布:nba湖人英格拉姆数据 编辑:程序博客网 时间:2024/06/04 19:53
  1. public class OkHttp3Util {  
  2.   
  3.     /**  
  4.      * 懒汉 安全 加同步  
  5.      * 私有的静态成员变量 只声明不创建  
  6.      * 私有的构造方法  
  7.      * 提供返回实例的静态方法  
  8.      */  
  9.     private static OkHttpClient okHttpClient = null;  
  10.   
  11.   
  12.     private OkHttp3Util() {  
  13.     }  
  14.   
  15.     public static OkHttpClient getInstance() {  
  16.         if (okHttpClient == null) {  
  17.             //加同步安全  
  18.             synchronized (OkHttp3Util.class) {  
  19.                 if (okHttpClient == null) {  
  20.                     //okhttp可以缓存数据....指定缓存路径  
  21.                     File sdcache = new File(Environment.getExternalStorageDirectory(), "cache");  
  22.                     //指定缓存大小  
  23.                     int cacheSize = 10 * 1024 * 1024;  
  24.   
  25.                     okHttpClient = new OkHttpClient.Builder()//构建器  
  26.                             .connectTimeout(15, TimeUnit.SECONDS)//连接超时  
  27.                             .writeTimeout(20, TimeUnit.SECONDS)//写入超时  
  28.                             .readTimeout(20, TimeUnit.SECONDS)//读取超时  
  29.   
  30.                             //.addInterceptor(new CommonParamsInterceptor())//添加的是应用拦截器...公共参数  
  31.                             //.addNetworkInterceptor(new CacheInterceptor())//添加的网络拦截器  
  32.   
  33.                             .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))//设置缓存  
  34.                             .build();  
  35.                 }  
  36.             }  
  37.   
  38.         }  
  39.   
  40.         return okHttpClient;  
  41.     }  
  42.   
  43.     /**  
  44.      * get请求  
  45.      * 参数1 url  
  46.      * 参数2 回调Callback  
  47.      */  
  48.   
  49.     public static void doGet(String oldUrl, Callback callback) {  
  50.   
  51.         //要添加的公共参数...map  
  52.         Map<String,String> map = new HashMap<>();  
  53.         map.put("source","android");  
  54.   
  55.         StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder  
  56.   
  57.         stringBuilder.append(oldUrl);  
  58.   
  59.         if (oldUrl.contains("?")){  
  60.             //?在最后面....2类型  
  61.             if (oldUrl.indexOf("?") == oldUrl.length()-1){  
  62.   
  63.             }else {  
  64.                 //3类型...拼接上&  
  65.                 stringBuilder.append("&");  
  66.             }  
  67.         }else {  
  68.             //不包含? 属于1类型,,,先拼接上?号  
  69.             stringBuilder.append("?");  
  70.         }  
  71.   
  72.         //添加公共参数....  
  73.         for (Map.Entry<String,String> entry: map.entrySet()) {  
  74.             //拼接  
  75.             stringBuilder.append(entry.getKey())  
  76.                     .append("=")  
  77.                     .append(entry.getValue())  
  78.                     .append("&");  
  79.         }  
  80.   
  81.         //删掉最后一个&符号  
  82.         if (stringBuilder.indexOf("&") != -1){  
  83.             stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));  
  84.         }  
  85.   
  86.         String newUrl = stringBuilder.toString();//新的路径  
  87.   
  88.   
  89.         //创建OkHttpClient请求对象  
  90.         OkHttpClient okHttpClient = getInstance();  
  91.         //创建Request  
  92.         Request request = new Request.Builder().url(newUrl).build();  
  93.         //得到Call对象  
  94.         Call call = okHttpClient.newCall(request);  
  95.         //执行异步请求  
  96.         call.enqueue(callback);  
  97.   
  98.   
  99.     }  
  100.   
  101.     /**  
  102.      * post请求  
  103.      * 参数1 url  
  104.      * 参数2 Map<String, String> params post请求的时候给服务器传的数据  
  105.      *      add..("","")  
  106.      *      add()  
  107.      */  
  108.   
  109.     public static void doPost(String url, Map<String, String> params, Callback callback) {  
  110.         //要添加的公共参数...map  
  111.         Map<String,String> map = new HashMap<>();  
  112.         map.put("source","android");  
  113.   
  114.   
  115.         //创建OkHttpClient请求对象  
  116.         OkHttpClient okHttpClient = getInstance();  
  117.         //3.x版本post请求换成FormBody 封装键值对参数  
  118.   
  119.         FormBody.Builder builder = new FormBody.Builder();  
  120.         //遍历集合  
  121.         for (String key : params.keySet()) {  
  122.             builder.add(key, params.get(key));  
  123.   
  124.         }  
  125.   
  126.         //添加公共参数  
  127.         for (Map.Entry<String,String> entry: map.entrySet()) {  
  128.             builder.add(entry.getKey(),entry.getValue());  
  129.         }  
  130.   
  131.         //创建Request  
  132.         Request request = new Request.Builder().url(url).post(builder.build()).build();  
  133.   
  134.         Call call = okHttpClient.newCall(request);  
  135.         call.enqueue(callback);  
  136.   
  137.     }  
  138.   
  139.     /**  
  140.      * post请求上传文件....包括图片....流的形式传任意文件...  
  141.      * 参数1 url  
  142.      * file表示上传的文件  
  143.      * fileName....文件的名字,,例如aaa.jpg  
  144.      * params ....传递除了file文件 其他的参数放到map集合  
  145.      *  
  146.      */  
  147.     public static void uploadFile(String url, File file, String fileName,Map<String,String> params) {  
  148.         //创建OkHttpClient请求对象  
  149.         OkHttpClient okHttpClient = getInstance();  
  150.   
  151.         MultipartBody.Builder builder = new MultipartBody.Builder();  
  152.         builder.setType(MultipartBody.FORM);  
  153.   
  154.         //参数  
  155.         if (params != null){  
  156.             for (String key : params.keySet()){  
  157.                 builder.addFormDataPart(key,params.get(key));  
  158.             }  
  159.         }  
  160.         //文件...参数name指的是请求路径中所接受的参数...如果路径接收参数键值是fileeeee,此处应该改变  
  161.         builder.addFormDataPart("file",fileName,RequestBody.create(MediaType.parse("application/octet-stream"),file));  
  162.   
  163.         //构建  
  164.         MultipartBody multipartBody = builder.build();  
  165.   
  166.         //创建Request  
  167.         Request request = new Request.Builder().url(url).post(multipartBody).build();  
  168.   
  169.         //得到Call  
  170.         Call call = okHttpClient.newCall(request);  
  171.         //执行请求  
  172.         call.enqueue(new Callback() {  
  173.             @Override  
  174.             public void onFailure(Call call, IOException e) {  
  175.                 Log.e("upload",e.getLocalizedMessage());  
  176.             }  
  177.   
  178.             @Override  
  179.             public void onResponse(Call call, Response response) throws IOException {  
  180.                 //上传成功回调 目前不需要处理  
  181.                 if (response.isSuccessful()){  
  182.                     String s = response.body().string();  
  183.                     Log.e("upload","上传--"+s);  
  184.                 }  
  185.             }  
  186.         });  
  187.   
  188.     }  
  189.   
  190.     /**  
  191.      * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}  
  192.      * 参数一:请求Url  
  193.      * 参数二:请求的JSON  
  194.      * 参数三:请求回调  
  195.      */  
  196.     public static void doPostJson(String url, String jsonParams, Callback callback) {  
  197.         RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);  
  198.         Request request = new Request.Builder().url(url).post(requestBody).build();  
  199.         Call call = getInstance().newCall(request);  
  200.         call.enqueue(callback);  
  201.   
  202.     }  
  203.   
  204.     /**  
  205.      * 下载文件 以流的形式把apk写入的指定文件 得到file后进行安装  
  206.      * 参数er:请求Url  
  207.      * 参数san:保存文件的文件夹....download  
  208.      */  
  209.     public static void download(final Activity context, final String url, final String saveDir) {  
  210.         Request request = new Request.Builder().url(url).build();  
  211.         Call call = getInstance().newCall(request);  
  212.         call.enqueue(new Callback() {  
  213.             @Override  
  214.             public void onFailure(Call call, IOException e) {  
  215.                 //com.orhanobut.logger.Logger.e(e.getLocalizedMessage());  
  216.             }  
  217.   
  218.             @Override  
  219.             public void onResponse(Call call, final Response response) throws IOException {  
  220.   
  221.                 InputStream is = null;  
  222.                 byte[] buf = new byte[2048];  
  223.                 int len = 0;  
  224.                 FileOutputStream fos = null;  
  225.                 try {  
  226.                     is = response.body().byteStream();//以字节流的形式拿回响应实体内容  
  227.                     //apk保存路径  
  228.                     final String fileDir = isExistDir(saveDir);  
  229.                     //文件  
  230.                     File file = new File(fileDir, getNameFromUrl(url));  
  231.   
  232.                     fos = new FileOutputStream(file);  
  233.                     while ((len = is.read(buf)) != -1) {  
  234.                         fos.write(buf, 0, len);  
  235.                     }  
  236.   
  237.                     fos.flush();  
  238.   
  239.                     context.runOnUiThread(new Runnable() {  
  240.                         @Override  
  241.                         public void run() {  
  242.                             Toast.makeText(context, "下载成功:" + fileDir + "," + getNameFromUrl(url), Toast.LENGTH_SHORT).show();  
  243.                         }  
  244.                     });  
  245.   
  246.                     //apk下载完成后 调用系统的安装方法  
  247.                     Intent intent = new Intent(Intent.ACTION_VIEW);  
  248.                     intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");  
  249.                     context.startActivity(intent);  
  250.   
  251.   
  252.                 } catch (IOException e) {  
  253.                     e.printStackTrace();  
  254.                 } finally {  
  255.                     if (is != null) is.close();  
  256.                     if (fos != null) fos.close();  
  257.   
  258.   
  259.                 }  
  260.             }  
  261.         });  
  262.   
  263.     }  
  264.   
  265.     /**  
  266.      * 判断下载目录是否存在......并返回绝对路径  
  267.      *  
  268.      * @param saveDir  
  269.      * @return  
  270.      * @throws IOException  
  271.      */  
  272.     public static String isExistDir(String saveDir) throws IOException {  
  273.         // 下载位置  
  274.         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {  
  275.   
  276.             File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);  
  277.             if (!downloadFile.mkdirs()) {  
  278.                 downloadFile.createNewFile();  
  279.             }  
  280.             String savePath = downloadFile.getAbsolutePath();  
  281.             Log.e("savePath", savePath);  
  282.             return savePath;  
  283.         }  
  284.         return null;  
  285.     }  
  286.   
  287.     /**  
  288.      * @param url  
  289.      * @return 从下载连接中解析出文件名  
  290.      */  
  291.     private static String getNameFromUrl(String url) {  
  292.         return url.substring(url.lastIndexOf("/") + 1);  
  293.     }  
  294.   
  295.     /**  
  296.      * 公共参数拦截器  
  297.      */  
  298.     private static class CommonParamsInterceptor implements Interceptor{  
  299.   
  300.         //拦截的方法  
  301.         @Override  
  302.         public Response intercept(Chain chain) throws IOException {  
  303.   
  304.             //获取到请求  
  305.             Request request = chain.request();  
  306.             //获取请求的方式  
  307.             String method = request.method();  
  308.             //获取请求的路径  
  309.             String oldUrl = request.url().toString();  
  310.   
  311.             Log.e("---拦截器",request.url()+"---"+request.method()+"--"+request.header("User-agent"));  
  312.   
  313.             //要添加的公共参数...map  
  314.             Map<String,String> map = new HashMap<>();  
  315.             map.put("source","android");  
  316.   
  317.             if ("GET".equals(method)){  
  318.                 // 1.http://www.baoidu.com/login                --------? key=value&key=value  
  319.                 // 2.http://www.baoidu.com/login?               --------- key=value&key=value  
  320.                 // 3.http://www.baoidu.com/login?mobile=11111    -----&key=value&key=value  
  321.   
  322.                 StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder  
  323.   
  324.                 stringBuilder.append(oldUrl);  
  325.   
  326.                 if (oldUrl.contains("?")){  
  327.                     //?在最后面....2类型  
  328.                     if (oldUrl.indexOf("?") == oldUrl.length()-1){  
  329.   
  330.                     }else {  
  331.                         //3类型...拼接上&  
  332.                         stringBuilder.append("&");  
  333.                     }  
  334.                 }else {  
  335.                     //不包含? 属于1类型,,,先拼接上?号  
  336.                     stringBuilder.append("?");  
  337.                 }  
  338.   
  339.                //添加公共参数....  
  340.                 for (Map.Entry<String,String> entry: map.entrySet()) {  
  341.                     //拼接  
  342.                     stringBuilder.append(entry.getKey())  
  343.                             .append("=")  
  344.                             .append(entry.getValue())  
  345.                             .append("&");  
  346.                 }  
  347.   
  348.                 //删掉最后一个&符号  
  349.                 if (stringBuilder.indexOf("&") != -1){  
  350.                     stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));  
  351.                 }  
  352.   
  353.                 String newUrl = stringBuilder.toString();//新的路径  
  354.   
  355.                 //拿着新的路径重新构建请求  
  356.                 request = request.newBuilder()  
  357.                         .url(newUrl)  
  358.                         .build();  
  359.   
  360.   
  361.             }else if ("POST".equals(method)){  
  362.                 //先获取到老的请求的实体内容  
  363.                 RequestBody oldRequestBody = request.body();//....之前的请求参数,,,需要放到新的请求实体内容中去  
  364.   
  365.                 //如果请求调用的是上面doPost方法  
  366.                 if (oldRequestBody instanceof FormBody){  
  367.                     FormBody oldBody = (FormBody) oldRequestBody;  
  368.   
  369.                     //构建一个新的请求实体内容  
  370.                     FormBody.Builder builder = new FormBody.Builder();  
  371.                     //1.添加老的参数  
  372.                     for (int i=0;i<oldBody.size();i++){  
  373.                         builder.add(oldBody.name(i),oldBody.value(i));  
  374.                     }  
  375.                     //2.添加公共参数  
  376.                     for (Map.Entry<String,String> entry:map.entrySet()) {  
  377.   
  378.                         builder.add(entry.getKey(),entry.getValue());  
  379.                     }  
  380.   
  381.                     FormBody newBody = builder.build();//新的请求实体内容  
  382.   
  383.                     //构建一个新的请求  
  384.                     request = request.newBuilder()  
  385.                             .url(oldUrl)  
  386.                             .post(newBody)  
  387.                             .build();  
  388.                 }  
  389.   
  390.   
  391.             }  
  392.   
  393.   
  394.             Response response = chain.proceed(request);  
  395.   
  396.             return response;  
  397.         }  
  398.     }  
  399.   
  400.     /**  
  401.      * 网络缓存的拦截器......注意在这里更改cache-control头是很危险的,一般客户端不进行更改,,,,服务器端直接指定  
  402.      *  
  403.      * 没网络取缓存的时候,一般都是在数据库或者sharedPerfernce中取出来的  
  404.      *  
  405.      *  
  406.      *  
  407.      */  
  408.     /*private static class CacheInterceptor implements Interceptor{  
  409.   
  410.         @Override  
  411.         public Response intercept(Chain chain) throws IOException {  
  412.             //老的响应  
  413.             Response oldResponse = chain.proceed(chain.request());  
  414.   
  415.             *//*if (NetUtils.isNetworkConnected(DashApplication.getAppContext())){  
  416.                 int maxAge = 120; // 在线缓存在2分钟内可读取  
  417.   
  418.                 return oldResponse.newBuilder()  
  419.                         .removeHeader("Pragma")  
  420.                         .removeHeader("Cache-Control")  
  421.                         .header("Cache-Control", "public, max-age=" + maxAge)  
  422.                         .build();  
  423.             }else {  
  424.                 int maxStale = 60 * 60 * 24 * 14; // 离线时缓存保存2周  
  425.                 return oldResponse.newBuilder()  
  426.                         .removeHeader("Pragma")  
  427.                         .removeHeader("Cache-Control")  
  428.                         .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)  
  429.                         .build();  
  430.             }*//*  
  431.   
  432.         }  
  433.     }*/  
  434. }
原创粉丝点击