Android Okhttp封装get,post请求以及上传图片带参数,无参详解

和以往的套路一样,先导入一个依赖包:
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。

下面给大家写一个简单好用的okhttp网络请求工具类,分为两个请求方式(get和post请求),简单说一下get和post的区别:

1.当发送数据的时候,get的url是有长度限制的(最大长度是2048),而post是没有限制   

2.get的安全性较差,post请求比get请求更安全get请求会把参数保留在浏览网页中,而post不会保存到浏览器的历史或服务器日志中  

3.直接请求数据就用get , 如果需要给后台传数据那就用post

import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by Administrator on 2019/7/18.
 */

public class OkhttpUtils {
    private static final String TAG="OkhttpUtils";
    private OkHttpClient mClient;
    private  static volatile OkhttpUtils mOkUtils;//防止多个线程同时访问
    public static final int TIMEOUT = 1000 * 5;
    private Handler handler = new Handler(Looper.getMainLooper());
    //json请求
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    //使用构造方法初始化
    public OkhttpUtils(){
        mClient=new OkHttpClient();
    }
    //使用单利模式,通过获取的方式拿到对象(还为了优化内存,单利模式只可创建一次)z
    public static OkhttpUtils getInstance(){
        if(mOkUtils==null){
            synchronized (OkhttpUtils.class){
                if(mOkUtils==null){
                    mOkUtils=new OkhttpUtils();
                    mOkUtils.initUtils();
                }
            }
        }
        return mOkUtils;
    }
    /**
     * 应用拦截器
     */
    Interceptor appInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            HttpUrl url = request.url();
            String s = url.url().toString();
            //———请求之前—–
            Log.d(TAG,"app interceptor:begin");
            Response  response = chain.proceed(request);
            Log.d(TAG,"app interceptor:end");
            //———请求之后————
            return response;
    }

    };
    private void initUtils(){
        mClient.newBuilder()
                .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(TIMEOUT, TimeUnit.SECONDS)
                //拦截器
                .addInterceptor(appInterceptor)
                .build();
    }
    /**
     * okhttp     get 请求
     * **/
    public void getJson(String url,final HttpCallBack callBack){
        Request request=new Request.Builder()
                .url(url)
                .get()
                .build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (e instanceof SocketTimeoutException) {
                    OnError(callBack, "连接超时");
                } else if (e instanceof ConnectException) {
                    OnError(callBack, "连接服务器失败");
                } else if (e instanceof UnknownHostException) {
                    OnError(callBack, "网络异常");
                } else {
                    OnError(callBack, "未知错误");
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String string = response.body().string();
                onSuccess(callBack,string);
            }
        });

    }
    /**
     * okhttp    post请求
     * */
    public void postJson(String url, String json, final HttpCallBack callBack){
        RequestBody requestBody=RequestBody.create(JSON,json);
        Request request=null;
        request=new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (e instanceof SocketTimeoutException) {
                    OnError(callBack, "连接超时");
                } else if (e instanceof ConnectException) {
                    OnError(callBack, "连接服务器失败");
                } else if (e instanceof UnknownHostException) {
                    OnError(callBack, "网络异常");
                } else {
                    OnError(callBack, "未知错误");
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String string = response.body().string();
                onSuccess(callBack,string);
            }
        });

    }
    public void onSuccess(final HttpCallBack callBack, final String data) {
        if (callBack != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {//在主线程操作
                    callBack.onSusscess(data);
                }
            });
        }
    }


    public void OnError(final HttpCallBack callBack, final String msg) {
        if (callBack != null) {
            handler.post(new Runnable() {
                @Override


                public void run() {
                    callBack.onError(msg);
                }

            });
        }
    }
    public static abstract class HttpCallBack {
        //成功回调
        public abstract void onSusscess(String data);
        //失败
        public abstract void onError(String meg);

    }

}

为了一下初学的萌生,调用方法也推荐一下,用下面的方式调用(下面只粘贴了get请求,post请求的话就把get换成post,即可,这工具类都可以更改,有的公司要session ,有的公司需要cookie,你们可以根据自己的需求在我封装的网络请求类里面,把相关参数放在请求头里面即可):

    OkhttpUtils.getInstance().getJson(str, new OkhttpUtils.HttpCallBack() {
                    @Override
                    public void onSusscess(String data) {

                    }

                    @Override
                    public void onError(String meg) {
                    }
                });

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

我封装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);
        }
    }

}

 

 

 

 

 

 


 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值