OkHttp使用详解
发布日期:2025-04-28 00:27:20 浏览次数:75 分类:精选文章

本文共 5784 字,大约阅读时间需要 19 分钟。

OkHttp快速入门与实践指南

今天我花时间深入学习了OkHttp框架,并整理了一些实用的使用手册,希望能为有需要的开发者提供帮助。


一、OkHttp简介

OkHttp是一个强大且灵活的网络请求框架,广泛应用于Android开发中。相比Google提供的Volley,OkHttp的优势在于支持Android6.0及以上版本的Http客户端请求。

二、OkHttp GET 请求

1.基础步骤

  • 创建OkHttpClient对象:
OkHttpClient client = new OkHttpClient();
  • 构建GET请求:
Request request = new Request.Builder()    .get()    .url("https://www.baidu.com")    .build();
  • 发送请求:
Call call = client.newCall(request);call.enqueue(new Callback() {    @Override    public void onFailure(Call call, IOException e) {        Toast.makeText(context, "请求失败", Toast.LENGTH_SHORT).show();    }    @Override    public void onResponse(Call call, Response response) throws IOException {        String res = response.body().string();        runOnUiThread(() -> {            contentTv.setText(res);        });    }});

2.注意事项

  • 同步请求:适用于简单场景,但会阻塞UI thread。
  • 异步请求:推荐使用,需在子 thread中更新UI。

三、OkHttp POST 请求

1.提交键值对

  • 创建FormBody:
FormBody formBody = new FormBody.Builder()    .add("username", "admin")    .add("password", "admin")    .build();
  • 构建POST请求:
Request request = new Request.Builder()    .post(formBody)    .url("http://www.jianshu.com/")    .build();

2.发送请求

Call call = client.newCall(request);call.enqueue(new Callback() {    @Override    public void onFailure(Call call, IOException e) {        Toast.makeText(context, "Post Failed", Toast.LENGTH_SHORT).show();    }    @Override    public void onResponse(Call call, Response response) throws IOException {        String res = response.body().string();        runOnUiThread(() -> {            contentTv.setText(res);        });    }});

四、Post提交字符串

有时我们需要向服务器发送自定义字符串。可以使用以下方法:

RequestBody requestBody = RequestBody.create(    MediaType.parse("text/plain;charset=utf-8"),    "{username:admin;password:admin}");

五、文件上传

1.上传本地文件

File file = new File Environment.getExternalStorageDirectory(), "1.png");if (!file.exists()) {    Toast.makeText(context, "文件不存在", Toast.LENGTH_SHORT).show();} else {    RequestBody requestBody = RequestBody.create(        MediaType.parse("application/octet-stream"),        file    );    // 使用自定义的CountingRequestBody进行进度跟踪    CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, listener);        Call call = client.newCall(RequestBuilder()        .post(countingRequestBody)        .build());        call.enqueue(new Callback() {        @Override        public void onFailure(Call call, IOException e) {            // 处理失败        }        @Override        public void onResponse(Call call, Response response) throws IOException {            // 处理成功        }    });}

2.添加存储卡读写权限

在AndroidManifest.xml中添加:


六、表单提交

1.构建MultipartBody

File file = new File(Environment.getExternalStorageDirectory(), "1.png");if (!file.exists()) {    Toast.makeText(context, "文件不存在", Toast.LENGTH_SHORT).show();    return;}RequestBody multipartBody = new MultipartBody.Builder()    .setType(MultipartBody.FORM)    .addFormDataPart("username", "admin")    .addFormDataPart("password", "admin")    .addFormDataPart("myfile", "1.png", RequestBody.create(        MediaType.parse("application/octet-stream"),        file    ))    .build();

七、文件下载

1.下载文件到存储卡

public void downloadImg(View view) {    OkHttpClient client = new OkHttpClient();    Request request = new Request.Builder()        .get()        .url("https://www.baidu.com/img/bd_logo1.png")        .build();        Call call = client.newCall(request);    call.enqueue(new Callback() {        @Override        public void onFailure(Call call, IOException e) {            Log.e("moer", "下载失败");        }        @Override        public void onResponse(Call call, Response response) throws IOException {            InputStream is = response.body().byteStream();            File file = new File(Environment.getExternalStorageDirectory(), "n.png");            FileOutputStream fos = new FileOutputStream(file);            byte[] buf = new byte[128];            int len = 0;            while ((len = is.read(buf)) != -1) {                fos.write(buf, 0, len);            }            fos.flush();            fos.close();            is.close();        }    });}

八、进度条显示

1.下载进度

@Overridepublic void onResponse(Call call, Response response) throws IOException {    InputStream is = response.body().byteStream();    long total = response.body().contentLength();    long sum = 0;    byte[] buf = new byte[128];    FileOutputStream fos = new FileOutputStream(file);        while ((len = is.read(buf)) != -1) {        fos.write(buf, 0, len);        sum += len;        runOnUiThread(() -> {            contentTv.setText(sum + "/" + total);        });    }        fos.close();    is.close();}

2.上传进度

创建自定义的CountingRequestBody:

public class CountingRequestBody extends RequestBody {    private RequestBody delegate;    private Listener listener;        public CountingRequestBody(RequestBody delegate, Listener listener) {        this.delegate = delegate;        this.listener = listener;    }        @Override    public MediaType contentType() {        return delegate.contentType();    }        @Override    public void writeTo(BufferedSink sink) throws IOException {        delegate.writeTo(Okio.buffer(new CountingSink(sink)));    }        protected final class CountingSink extends ForwardingSink {        private long byteWritten;                public CountingSink(Sink sink) {            super(sink);        }                @Override        public void write(Buffer source, long byteCount) throws IOException {            super.write(source, byteCount);            byteWritten += byteCount;            listener.onRequestProgress(byteWritten, contentLength());        }    }        public static interface Listener {        void onRequestProgress(long byteWritten, long contentLength);    }}

结语

以上就是对OkHttp的一些实用示例和技巧,希望能为开发者提供帮助。通过合理使用OkHttp,可以轻松实现各种网络请求场景。如果有任何问题或需要更深入的内容,欢迎在评论区留言。

上一篇:OKhttp使用详解(二)
下一篇:2025年04月27日AI领域重点关注焦点

发表评论

最新留言

表示我来过!
[***.240.166.169]2026年06月08日 23时19分48秒