Android Okhttp封装详解

和以往的套路一样,先导入一个 依赖包

implementation 'com.squareup.okhttp3:okhttp:3.9.0'

    我封装的是一个Okhttp工具类,有get请求,有post请求,还有上传照片文件功能,我先一步一步的解析这几个方法,最下面是一个封装好的工具类,复制粘贴即可使用:

Okhttp优点:

    1. 支持 SPDY ,允许连接同一主机的所有请求分享一个socket。

    2. 如果SPDY不可用,会使用连接池减少请求延迟。

    3. 使用GZIP压缩下载内容,且压缩操作对用户是透明的。

    4. 利用响应缓存来避免重复的网络请求。

Okhttp特点:

    1. 当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。

    2. 如果你的服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。 

    3. OKHttp利用TLS的特性初始化新的连接,如果握手失败便退回到SSLV3。

    4. OKHttp的使用很简单。其2.0API拥有流畅的构建器和稳定性。它支持同步阻塞请求和异步回调请求。

    5. 你可以试试OKHttp而不重写网络代码。okhttp-urlconnection模块实现了都很熟悉的Java.net.HttpURLConnection的API,okhttp-apache模块实现了Apache的HttpClient的API。

    6. OKHttp支持android2.3以上,Java支持最低版本1.7。

代码介绍:

这个是一个get请求,只需在调用方,类名.getString();就能使用了,里面是两个参数,一个是需要传进去的Url , 另一个直接new 一个接口就行了,然后在onResponse方法里做自己要做操作就行。

public static void getString(String url,Callback callback){
    Request request = new Request.Builder()
            .url(url)
            .build();
    Call call = getInstance().newCall(request);
    call.enqueue(callback);
}

post请求,需要在方法里面写入一个键值对,在这里我写了一个Map集合用来存放键值对,调用方法也是   类名.方法();具体操作根据自己的需求。

public static void postString(String url,Map<String, String> map,Callback callback){
    FormBody.Builder builder=new FormBody.Builder();
    //遍历map中所有的参数到builder
    for (String key : map.keySet()) {
        builder.add(key, map.get(key));
        Log.e("", "key: "+key+"   map.get:  "+map.get(key));
    }
    Request request = new Request.Builder()
            .url(url)
            .post(builder.build())
            .build();
    Call call = getInstance().newCall(request);
    call.enqueue(callback);
}

下面是上传照片、图片文件,多张图片带参数的例子,套路都差不多,多了就找一个方法管理就行了,我就把完整的代码展示出来了。

我封装Okhttp用的是单例模式,单例模式的特性就是只允许创建一个实例,能减少内存的消耗,代码里面也有注释,请大家好好看一下吧。

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.util.Log;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * OKHttp3上传工具类
 * */
public class OkhttpUtils {

    private Context ctx;
    private static OkHttpClient ok = null;
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    private Map<String, String> map = new HashMap<String, String>();//存放
    private List<String> list = new ArrayList<String>();
    private static File file;
    private static String imgpath;
    private static String imageName;

    private OkhttpUtils() {

    }

    ;

    /*
     *单例获取
     * */
    public static OkHttpClient getInstance() {
        if (ok == null) {
            synchronized (OkhttpUtils.class) {
                if (ok == null)
                    ok = new OkHttpClient();
            }
        }
        return ok;
    }

    public static void getString(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /*
     * 键值对上传数据
     * */
    public static void postString(String url, Map<String, String> map, Callback callback) {
        FormBody.Builder builder = new FormBody.Builder();
        //遍历map中所有的参数到builder
        for (String key : map.keySet()) {
            builder.add(key, map.get(key));
            Log.e("", "key: " + key + "   map.get:  " + map.get(key));
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /*
     * 上传一张图片带参数
     * */
    public static void UploadFileCS(String url, String key1, String path, Map<String, String> map, Callback callback) {
//      path.lastIndexOf是找到uri里面最后一个"你想找的东西"的位置,所以就是截取最后一个"/"和最后一个"."之间的东西,
        String imagpath = path.substring(0, path.lastIndexOf("/"));

        String imgName[] = path.split("/");
        for (int i = 0; i < imgName.length; i++) {
            if (i == imgName.length - 1) {
                String name = imgName[i];
                file = new File(imagpath, name);
            }
        }
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        RequestBody fileBody = RequestBody.create(MEDIA_TYPE_PNG, file);
        //遍历map中所有的参数到builder
        for (String key : map.keySet()) {
            builder.addFormDataPart(key, map.get(key));
        }
        //讲文件添加到builder中
        builder.addFormDataPart(key1, file.getName(), fileBody);
        //创建请求体
        RequestBody requestBody = builder.build();

        Request request = new Request.Builder().url(url).post(requestBody).build();
        Call call = getInstance().newCall(request);
        call.enqueue(callback);
    }

    /*
     *上传多个图片文件
     * */
    @SuppressWarnings("unused")
    public static void UploadFileMore(String url, List<String> paths, Callback callback) {
        if (paths != null) {
            //创建文件集合
            List<File> list = new ArrayList<File>();
            //遍历整个图片地址
            for (String str : paths) {
                //截取图片地址:/storage/emulated/0
                imgpath = str.substring(0, str.lastIndexOf("/"));
                //将图片路径分解成String数组
                String[] imgName = str.split("/");
                for (int i = 0; i < imgName.length; i++) {
                    if (i == imgName.length - 1) {
                        imageName = imgName[i];//获取图片名称
                        File file = new File(imgpath, imageName);
                        list.add(file);
                    }
                }
            }
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);//设置表单类型
            //遍历图片文件
            for (File file : list) {
                if (file != null) {
                    builder.addFormDataPart("acrd", file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
                }
            }
            //构建请求体
            MultipartBody requestBody = builder.build();
            Request request = new Request.Builder().url(url).post(requestBody).build();
            Call call = getInstance().newCall(request);
            call.enqueue(callback);
        }

    }

    /*
     * 上传多张图片带参数
     * */
    @SuppressWarnings("unused")
    public static void UploadFileSCMore(String url, String value, List<String> paths, Map<String, String> map, Callback callback) {
        if (paths != null && map != null) {
            //创建文件集合
            List<File> list = new ArrayList<File>();
            //遍历整个图片地址
            for (String str : paths) {
                //截取图片地址:/storage/emulated/0
                imgpath = str.substring(0, str.lastIndexOf("/"));
                //将图片路径分解成String数组
                String[] imgName = str.split("/");
                for (int i = 0; i < imgName.length; i++) {
                    if (i == imgName.length - 1) {
                        imageName = imgName[i];//获取图片名称
                        File file = new File(imgpath, imageName);
                        list.add(file);
                    }
                }
            }
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);//设置表单类型
            //遍历图片文件
            for (File file : list) {
                if (file != null) {
                    builder.addFormDataPart(value, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
                }
            }
            //遍历map中所有的参数到builder
            for (String key : map.keySet()) {
                builder.addFormDataPart(key, map.get(key));
            }
            RequestBody requestBody = builder.build();

            Request request = new Request.Builder().url(url).post(requestBody).build();
            Call call = getInstance().newCall(request);
            call.enqueue(callback);
        }
    }

}
(有时间了,我会给大家详解一下)

猜你喜欢

转载自blog.csdn.net/nazicsdn/article/details/79785831