Okhttp3菜鸟必入

本文详细介绍OkHttp3的使用方法,包括依赖添加、GET/POST请求、上传文件、下载文件、设置请求时间及缓存大小、Cookie管理、请求头设置等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为啥要学Okhttp3呢,因为Retrofit中用到了,而且它本身也是一个网络框架,不与Retrofit一起用还可以单独用,一石二鸟为啥不学呢。这个相对也比较简单。

一、添加依赖

    //Okhttp3,后面的那个依赖如果不添加,有说链接不上数据库的,所以还是加上吧,我没添加没啥问题,保险起见
    compile 'com.squareup.okhttp3:okhttp:3.3.0'
    compile 'com.squareup.okio:okio:1.7.0'

二、Get请求

这里 注意 注意 回调不是在主线程,更新View的时候要注意啦

这里返回的都是Call,之后在Retrofit中你也会看到的,返回的也是Call

/**
     * okHttp的Get请求
     *
     * call.execute()为同步方法
     * call.enqueue(new Callback())为异步方法
     *
     * OkHttp请求的回调不是主线程,可以用runOnUiThread方法回到主线程
     */
    private void okhttpGet() {
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder().url("https://www.baidu.com/").build();
        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

                Log.e("------------>","get请求失败"+e+"当前线程:"+Thread.currentThread().getName());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                Log.e("------------>","get请求成功"+response.body().string()+"当前线程:"+Thread.currentThread().getName());
            }
        });

    }

三、Post请求

RequestBody的数据格式都要指定Content-Type,常见的有三种:

  • 1、application/x-www-form-urlencoded 数据是个普通表单

    下面的例子中用的就是这个,可以看到我用的是FormBody,因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。

  • 2、application/json 数据是个json

    创建RequestBody时就不能用FormBody啦,要用RequestBody.create()

    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody body = RequestBody.create(JSON, "你的json");
  • 3、multipart/form-data 数据里有文件

    这个时候还有个新的东东MultipartBody;

    如下例子中的image/png还可以换成其他的如multipart/form-data,text/plain; charset=utf-8等

    RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM) //一定写哈
    .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
    .build();
  • 说明:如果一次上传多个内容,可重复利用addFormDataPart方法

    RequestBody body = new MultipartBody.Builder().addFormDataPart("","",RequestBody.create(MediaType.parse(""),bytes)).addFormDataPart("","",RequestBody.create(MediaType.parse(""),bytes)).build();

综上:okhttp,还有两种requestBody,一个是FormBody,一个是MultipartBody,前者以表单的方式传递简单的键值对,后者以POST表单的方式上传文件可以携带参数

private void okhttpPost() {

        //得到okHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //得到requestBody对象,用来承载参数
        RequestBody requestBody = new FormBody.Builder().add("telephone", "15811470200").add("password", "123456").build();
        //得到request对象,设置请求时的URL、头,参数等--->参数是在这设置的哦
        Request request = new Request.Builder().url("http://www.xxxx/api/rest/login")
                .post(requestBody)//参数
                .addHeader("xxxxxx","ssssss")//可以添加多个头
                .addHeader("ddddd","ssssss")
                .build();
        //得到call对象
        Call call = okHttpClient.newCall(request);
        //执行异步请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("------------>", "response post" + response.body().string());

            }
        });

    }

四、上传文件

/**
     * 上传文件,可以是byte数组,也可以是file文件
     *
     * 如下例子:上传文件同时还需要传其他类型的字段
     */
    private void okhttpPostFile(){

        File file = new File("");

        OkHttpClient okHttpClient = new OkHttpClient();

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("telephone","15811470299")
                .addFormDataPart("headimage","imageName",RequestBody.create(MediaType.parse("image/png"),file)).build();

        Request request = new Request.Builder().url("https://www.baidu.com").post(requestBody).addHeader("sss","sss").build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("-------------->","e"+e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                Log.e("-------------->","response"+response.body().string());
            }
        });

    }

五、下载文件

/**
     * 下载文件
     */
    private void okhttpDownFile(){

        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png").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 {
                //获取流
                InputStream inputStream = response.body().byteStream();
                Log.e("-------------->","length"+response.body().contentLength()+"当前线程:"+Thread.currentThread().getName());
                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                //因为回调不是主线程,要更新页面就要回到主线程
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ImageView imageView = new ImageView(OkHttp3Activity.this);
                        imageView.setImageBitmap(bitmap);
                        ((RelativeLayout)findViewById(R.id.activity_ok_http3)).addView(imageView);
                    }
                });
            }
        });
    }

六、设置请求时间、缓存大小

//设置超时时间和缓存
    private void okhttpSetTimeOutCache(){

        long cacheSize = 1024*1000*1000;

        OkHttpClient httpClient = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20,TimeUnit.SECONDS)
                .readTimeout(15,TimeUnit.SECONDS)
                .cache(new Cache(getExternalCacheDir().getAbsoluteFile(),cacheSize))
                .build();

    }

七、设置Cookie

private void okhttpCookie(){
        final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
                        cookieStore.put(httpUrl.host(), list);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl httpUrl) {
                        List<Cookie> cookies = cookieStore.get(httpUrl.host());
                        return cookies != null ? cookies : new ArrayList<Cookie>();
                    }
                })
                .build();
    }

八、设置请求头

看一看到两种方法,一个是addHeader(),一个是header(),两者区别:

1、在设置 HTTP 头时:
使用 header(name, value) 方法来设置 HTTP 头的唯一值。对同一个 HTTP 头,多次调用该方法会覆盖之前设置的值。
使用 addHeader(name, value) 方法来为 HTTP 头添加新的值。

 /**
     * okhttp添加请求头
     */
    private void okhttpAddHead() {

        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://www.xxxx/api/rest/session").addHeader("xxxx","xxxxx").header("sssss", "sssss").build();

        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("------------>", "response add" + response.body().string());
                Log.e("------------>", "response add" + response.message() + response.code());
                Log.e("------------>", "response add" + response.headers());//得到所有的头(服务器的头)
            }
        });

    }

参考文档
(http://www.cnblogs.com/yjpjy/p/5415778.html)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值