OkHttp3使用详解

OkHttp3是一款非常高效的http框架,下面进行简单的介绍:
1、使用单例模式声明OkHttp3的管理类

添加的依赖:
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.7.0'
权限:



因为会用到网络和sd卡上的数据,所以需要添加这些权限

public class OkHttpManager {
    public static final String TAG = "OkHttpManger";
    private static OkHttpClient okHttpClient;
    private static OkHttpManager manager;

    private OkHttpManager() {
        okHttpClient = new OkHttpClient();
    }

    public static OkHttpManager getInstance() {
        synchronized (OkHttpManager.class) {
            if (manager == null) {
                manager = new OkHttpManager();
                return manager;
            }
        }
        return manager;
    }
}

这里使用单例模式,保证只有一个OkManager和OkHttpClient 的实例。
2、普通同步get请求

        //通过Builder辅助类构建一个Request对象
        Request request = new Request.Builder().get().url(url).build();
        //通过同步执行获取一个Response对象
        Response response = okHttpClient.newCall(request).execute();
        //判断响应是否成功,如果成功的话,响应的内容会放在response.body()中
        if (response.isSuccessful()) {
            //字符串类型
            Log.i(TAG, "getData: " + response.body().string());
            //字节数组类型
            Log.i(TAG, "getData: " + response.body().bytes());
            //字节流类型
            Log.i(TAG, "getData: " + response.body().byteStream());
            //字符流类型
            Log.i(TAG, "getData: " + response.body().charStream());
        }

因为现在的Android主线程中不允许进行耗时操作,需要在调用该方法时将操作放在子线程中进行,避免出错!

3、异步GET请求

        //通过Builder辅助类构建一个Request对象
        Request request = new Request.Builder().get().url(url).build();
        //通过入队的方式,进行异步操作
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onFailure: 请求失败的时候调用该方法!");
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //字符串类型
                Log.i(TAG, "getData: " + response.body().string());
                //字节数组类型
                Log.i(TAG, "getData: " + response.body().bytes());
                //字节流类型
                Log.i(TAG, "getData: " + response.body().byteStream());
                //字符流类型
                Log.i(TAG, "getData: " + response.body().charStream());
            }
        });

在实际应用中几乎不可能用到同步方式,所以之后的POST方式介绍时就不写同步方式的了,如果有兴趣请自行Google!

4、POST方式提交字符串

  1. 构建一个RequestBody对象,我们在进行post方式提交的过程中需要将提交的内容封装到一个RequestBody中。
  2. 构建Request对象
  3. 异步请求
    /**
     * 使用post方式提交json字符串
     *
     * @param url     提交的路径
     * @param content 提交的内容
     */
    public void postString(String url, String content) {
        //构建一个RequestBody对象,,因为提交的是json字符串需要添加一个MediaType为"application/json",
        // 普通的字符串直接是null就可以了
        RequestBody requestBody = RequestBody.create(
            MediaType.parse("application/json"), content);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onFailure: " + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }

5、post提交键值对

    /**
     * 提交单个键值对
     *
     * @param url
     * @param key
     * @param value
     */
    public static void postKeyValuePaire(String url, String key, String value) {
        //提交键值对需要用到FormBody,因为FormBody是继承RequestBody的,所以拥有RequestBody的一切属性
        FormBody formBody = new FormBody.Builder()
                //添加键值对
                .add(key, value)
                .build();
        Request request = new Request.Builder()
                .post(formBody)
                .url(url)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }

6、使用post方式提交多个键值对

    /**
     * 提交多个键值对
     * @param url 提交的路径
     * @param map 用来放置键值对,map的key对应键,value对应值
     */
    public static void postKeyValuePaires(String url, Map map) {
        FormBody.Builder build = new FormBody.Builder();
        if (map != null) {
            //增强for循环遍历
            for (Map.Entry entry : map.entrySet()) {
                build.add(entry.getKey(), entry.getValue());
            }
        }
        FormBody formBody = build.build();

        Request request = new Request.Builder()
                .post(formBody)
                .url(url)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }

7、post方式提交单一文件

使用post方式提交文件时,我们一般需要获取文件的Mine值

    /**
     * 根据文件的名称判断文件的Mine值
     */
    private String getMediaType(String fileName) {
        FileNameMap map = URLConnection.getFileNameMap();
        String contentTypeFor = map.getContentTypeFor(fileName);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }
    /**
     * 上传单一文件
     */
    public void upLoadFile(String url, File file) {
        // //提交键值对需要用到MultipartBody,因为MultipartBody是继承RequestBody的,
        // 所以拥有RequestBody的一切属性,类似于javaEE中的表单提交
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        RequestBody fileBody = RequestBody.create(
                MediaType.parse(getMediaType(file.getName())), file);
        //这里的uploadfile是文件上传的标识,用于服务器识别文件
        builder.addFormDataPart("uploadfile", file.getName(), fileBody);
        MultipartBody body = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onFailure: ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }

8、post方式提交多个文件

    /**
     * 上传多个文件
     */
    public void upLoadFiles(String url, File[] files) {
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (int i = 0; i < files.length; i++) {
            RequestBody fileBody = RequestBody.create(MediaType.parse(getMediaType(files[i].getName())), files[i]);
            builder.addFormDataPart("uploadfile", files[i].getName(), fileBody);
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onFailure: ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }
9post方式提交多个文件和参数
    /**
     * 上传多个文件和参数
     */
    public void upLoadMultiFiles(String url, File[] files, Map map) {
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        //添加文件
        if (files.length != 0) {
            for (int i = 0; i < files.length; i++) {
                RequestBody fileBody = RequestBody.create(
                        MediaType.parse(getMediaType(files[i].getName())), files[i]);
                builder.addFormDataPart("uploadfile", files[i].getName(), fileBody);
            }
        }
        //添加参数
        if (map != null) {
            for (Map.Entry entry : map.entrySet()) {
                builder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "onFailure: ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, "onResponse: " + response.body().string());
            }
        });
    }

服务器源码

案例源码

你可能感兴趣的:(android)