OKHttp的使用(get,posh)的使用以及上传(下载)文件的简单使用

OkHttp3讲解

01,OkHttp3简介

1.支持http和https协议,api相同,易用;
2.http使用线程池,https使用多路复用;
3.okhttp支持同步和异步调用;
4.支持普通form和文件上传form;
5.操作请求和响应(日志,请求头,body等);
6.okhttp可以设置缓存;
7.支持透明的gzip压缩响应体
思路:

OkHttp3 使用思路

get请求思路

1.获取okHttpClient对象
2.构建Request对象
3.构建Call对象
4.通过Call.enqueue(callback)方法来提交异步请求;execute()方法实现同步请求

post请求思路

1.获取okHttpClient对象
2.创建RequestBody
3.构建Request对象
4.构建Call对象
5.通过Call.enqueue(callback)方法来提交异步请求;execute()方法实现同步请求

1.导入依赖

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

2.get实现请求代码(举例异步实现)

           //1.创建OkHttpClient对象
            OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
            //2.创建Request请求对象
            Request build = new Request.Builder()
                    .get()
                    .url("http://www.wanandroid.com/article/list/0/json?cid=60")
                    .build();
            //3.创建Call对象
            Call call = okHttpClient.newCall(build);
            //4.异步
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String string = response.body().string();
                    Log.e("zll", "onResponse: "+string);
         
                                //这里并不是主线程如果切换线程用一下方法
                                 runOnUiThread(new Runnable() {
                                         @Override
                                   public void run() {
                            
                                   }
                              });
                }
            });

3.poth实现请求(举例同步实现)

                //接口参数 String username,String password

                //第一步创建OKHttpClient
                OkHttpClient client = new OkHttpClient.Builder()
                        .build();
                //第二步创建RequestBody
                RequestBody body = new FormBody.Builder()
                        .add("username", "admin")
                        .add("password", "123456")
                        .build();
                //第三步创建Rquest
                Request request = new Request.Builder()
                        .url("http://yun918.cn/study/public/index.php/login")
                        .post(body)
                        .build();
                //第四步创建call回调对象
                final Call call = client.newCall(request);
                //第五步发起请求
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Response response = call.execute();
                            String result = response.body().string();
                            Log.i("response", result);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

4. 请求头处理(Header)以及超时和缓冲处理以及响应处理

//超时设置
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(5,TimeUnit.SECONDS)
.readTimeout(5,TimeUnit.SECONDS)
.writeTimeout(5,TimeUnit.SECONDS)
.cache(new Cache(cacheDirectory,1010241024))
.build();

//表单提交
RequestBody requestBody = new FormBody.Builder()
.add("pno", "1")
.add("ps","50")
.add("dtype","son")
.add("key","4a7cf244fd7efbd17ecbf0cb8e4d1c85")
.build();
//请求头设置
Request request = new Request.Builder()
.url(url)
.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
.header("User-Agent", "OkHttp Example")
.post(body)
.build();

//响应处理
@Override
public void onResponse(Call call, Response response) throws IOException {
//响应行
Log.d("ok", response.protocol() + " " +response.code() + " " + response.message());
//响应头
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
Log.d("ok", headers.name(i) + ":" + headers.value(i));
}
//响应体
final String string = response.body().string();
Log.d("ok", "onResponse: " + string);
runOnUiThread(new Runnable() {
@Override
public void run() {
tx.setText(string);
}
});
}

4. 请求体处理(Form表单,String字符串,流,文件)

//1.POST方式提交String/JSON application/json;json串
MediaType mediaType1 = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
String requestBody = "pno=1&ps=50&dtype=son&key=4a7cf244fd7efbd17ecbf0cb8e4d1c85";
RequestBody requestBody1 = RequestBody.create(mediaType1, requestBody);

//POST方式提交JSON:传递JSON同时设置son类型头
RequestBody requestBodyJson = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), "{要请求的数据需要解析}");
request.addHeader("Content-Type", "application/json")//必须加json类型头

//POST方式提交无参
RequestBody requestBody1 = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=utf-8"), "");

//2.POST方式提交流
RequestBody requestBody2 = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
sink.writeUtf8("pno=1&ps=50&dtype=son&key=4a7cf244fd7efbd17ecbf0cb8e4d1c85");
}
};

//3.POST方式提交表单
RequestBody requestBody4 = new FormBody.Builder()
.add("pno", "1")

            .add("ps","50")
            .add("dtype","son")
            .add("key","4a7cf244fd7efbd17ecbf0cb8e4d1c85")
            .build();

//4.POST提交文件
MediaType mediaType3 = MediaType.parse("text/x-markdown; charset=utf-8");
File file = new File("test.txt");
RequestBody requestBody3 = RequestBody.create(mediaType3, file);

//5.POST方式提交分块请求
MultipartBody body = new MultipartBody.Builder("AaB03x")
.setType(MultipartBody.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name="title""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name="image""),
RequestBody.create(MediaType.parse("image/png"), new File("website/static/logo-square.png")))
.build();

5.上传文件

1.权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

2.要添加动态权限

        /**
         * 动态获取权限,Android 6.0 新特性,一些保护权限,除了要在AndroidManifest中声明权限,还要使用如下代码动态获取
         */
        if (Build.VERSION.SDK_INT >= 23) {
            int REQUEST_CODE_CONTACT = 101;
            String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
            //验证是否许可权限
            for (String str : permissions) {
                if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
                    //申请权限
                    this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
                    return;
                }
            }
        }

3.方法使用

    private void initData() {
        // 1.获取文件
        String filePath = Environment.getExternalStorageDirectory() + File.separator + "bb.png";
        File file = new File(filePath);
        if (file.exists()) {
            Log.d(TAG, "exists: " + true);
        }
        // 2.创建文件上传请求对象
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);
        // 3.new okHttp
        OkHttpClient okHttpClient = new OkHttpClient();
        // 4.创建多媒体 请求对象
        RequestBody multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("key", "png")  // 文件上传的参数
                .addFormDataPart("file", file.getName(), fileBody)
                .build();

        //5. 创建request对象
        final Request request = new Request.Builder()
                .url(url)
                .post(multipartBody)
                .build();
        // 6 获取Call 请求对象
        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: ");
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            String string = response.body().string();
                            tv.setText(string);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        Log.d(TAG, "onResponse: " + "asdklj;aosldj");
                    }
                });
            }
        });
    }

6.上传文件带进度

    private void uploadFile() {
        // 1.获取文件
        String filePath = Environment.getExternalStorageDirectory() + File.separator + "aa.jpg";
        final File file = new File(filePath);
        if (file.exists()) {
            Log.d(TAG, "exists: " + true);
        }

        // file  --reqeustbody
//        RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file);
        RequestBody requestBody = new RequestBody() {
            @Override
            public MediaType contentType() { // 媒体 类型 image/jpg
                return MediaType.parse("image/jpg");
            }

            @Override
            public long contentLength() throws IOException { // 上传文件的长度
                return file.length();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException { // 从文件里通过流的形式写入到sink
                Source source;
                try {
                    source = Okio.source(file);
                    Buffer buf = new Buffer();
                    long filelength = contentLength();
                    long isReadSize = 0;// 每次读出的大小

                    long readCount = 0;// 计算已经写入的长度
                    while ((isReadSize = source.read(buf, 1024)) != -1) {
                        sink.write(buf, isReadSize);

                        // 进度值
                        readCount += isReadSize;// 计算已经写入的长度

                        int progress = (int) ((100 * readCount) / filelength);
                        Log.d(TAG, "writeTo: ==" + progress);

                        ProgressEvent progressEvent = new ProgressEvent();
                        progressEvent.position = progress + "";

                        EventBus.getDefault().post(progressEvent);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };


        MultipartBody multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), requestBody)
                .addFormDataPart("key", "hhh")
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();

        final Request request = new Request.Builder()
                .url("http://yun918.cn/study/public/file_upload.php")
                .post(multipartBody)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "onFailure: e=" + e.getMessage());
            }

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

                Log.d(TAG, "onResponse: response=" + response.body().string());
            }
        });

    }

7.下载带进度

    private void downLoadFile() {


        String filePath = Environment.getExternalStorageDirectory() + File.separator + "download.jpg";
        final File file = new File(filePath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        OkHttpClient okHttpClient = new OkHttpClient();

        Request request = new Request.Builder()
                .url("http://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png")
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

                Log.d(TAG, "onFailure: e="+e.getMessage());
            }

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

                //IO InputStream outputStream
                InputStream inputStream = response.body().byteStream();


                doStream(inputStream, file.getAbsolutePath());


            }
        });

    }

    /**
     * @param is       输入流  服务器
     * @param filePath 本地文件路径
     */
    public void doStream(InputStream is, String filePath)  {

        byte[] buf = new byte[2048];
        int len = 0;// 每次读取的长度
        FileOutputStream fos = null;
        File file = new File(filePath);
        try {
            long total = file.length();
            fos = new FileOutputStream(file);
            int sum = 0;
            int progress = 0;
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);// 写入 读取的长度
                sum += len;
                progress = (int) (sum * 100 / total);

                ProgressEvent progressEvent = new ProgressEvent();
                progressEvent.position = progress + "";
                EventBus.getDefault().post(progressEvent);
                Log.d(TAG, "progress:= " + progress + "%");
            }
            // 下载完成
            ProgressEvent progressEvent = new ProgressEvent();
            if (progress == 100) {
                progressEvent.position = "下载完成";
            }
            EventBus.getDefault().post(progressEvent);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
                fos.close();
                fos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }


}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容