转载

Android中OkHttp基础用法

目前Android中的网络请求最主要的就是UrlConnection和OkHttp了。而UrlConnection听说在安卓4.4以后也在内部实现了OkHttp。网络上OkHttp的封装框架也挺多比如鸿羊大神的okhttputils。框架虽有很多,基础我们更是需要了解的 ,看他们都是封装的啥内容。首先先从其最基本的用法开始

OkHttp的用法步骤:

引入最新的gradle依赖

compile 'com.squareup.okhttp3:okhttp:3.5.0'
    compile 'com.squareup.okio:okio:1.11.0'

Get:

  1. 创建okHttpClient的对象。我们可直接new出来 也可以通过OkHttpClient.Builder()构建。
  2. 创建Request对象。
  3. 封装成一个请求的任务Call
  4. 执行任务 call.execute();是同步请求直接返回Response但需要在子线程中执行。call.enqueue()时异步请求。内部一个执行的回调。

Post:

  1. 创建okHttpClient的对象。我们可直接new出来 也可以通过OkHttpClient.Builder()构建。
  2. 创建RequestBody
  3. 创建Request对象。
  4. 封装成一个请求的任务Call
  5. 执行任务 call.execute();是同步请求直接返回Response但需要在子线程中执行。call.enqueue()时异步请求。内部一个执行的回调。

示例代码:(官方文档)

package com.chs.okhttpdemo;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;

public class MainActivity extends AppCompatActivity {
    public static final MediaType MEDIA_TYPE_MARKDOWN
            = MediaType.parse("text/x-markdown; charset=utf-8");
    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("application/octet-stream");

    OkHttpClient okHttpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.拿到OkHttpClient对象
        okHttpClient = new OkHttpClient.Builder().
                connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
    }

    public void doGet(View view) {
        //创建request对象
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url("http://192.168.1.63:8080/album/login?name=chs&password=123").build();
        execute(request);
    }

    //post提交(表单)键值对
    public void doPost(View view) {
        //拿到body的构建器
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        builder.add("name", "chs")
                .add("password", "123");
        //拿到requestBody
        RequestBody requestBody = builder.build();
        //创建request对象
        Request request = new Request.Builder()
                .url("http://192.168.1.63:8080/album/login")
                .post(requestBody)
                .build();
        execute(request);
    }

    //post提交String   这个API最好不要发送大于1M的字符串
    public void doPostString(View view) {
        String postBody = "{name:chs,pwd:123}";
        //创建requestBody
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody);
        //创建request
        Request request = new Request.Builder()
                .url("http://192.168.1.63:8080/album/login")
                .post(requestBody)
                .build();
        execute(request);
    }
    //post提交流
    public void doPostStream(View view) {
        RequestBody requestBody = new RequestBody() {
            @Override
            public MediaType contentType() {
                return MEDIA_TYPE_MARKDOWN;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                sink.writeUtf8("doPostStream/n");
                sink.writeUtf8("{name:doPostStream,title:doPostStream}");
            }
        };

        Request request = new Request.Builder()
                .url("http://192.168.1.63:8080/album/login")
                .post(requestBody)
                .build();
        execute(request);
    }


    //post提交File
    public void doPostFile(View view) {
        //图片在手机上的路径
        String path = Environment.getExternalStorageDirectory().getPath()+"/BXT_SetPic/20170118/1484724630838.jpg";
        LogUtil.i("path:"+path);
        File file = new File(path);
        //创建requestBody
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, file);
        Request request = new Request.Builder()
                .url("http://192.168.1.63:8080/album/login")
                .post(requestBody)
                .build();
        execute(request);
    }
    //post提交Multipart   键值对和file一起提交
    public void doPostMultipart(View view) {
        //图片在手机上的路径
        String path = Environment.getExternalStorageDirectory().getPath()+"/BXT_SetPic/20170118/1484724630838.jpg";
        LogUtil.i("pth:"+path);
        File file = new File(path);
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("name", "Square")
                .addFormDataPart("password", "1111")
                .addFormDataPart("image", "1484724630838.jpg", RequestBody.create(MEDIA_TYPE_JPG, file))
                .build();
        //封装一层来获取上传的进度
        CountingRequestBody countRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.OnProgressListener() {
            @Override
            public void OnProgress(long byteWrite, long contentLength) {
                LogUtil.i(byteWrite+"/"+contentLength);
            }
        });
        Request request = new Request.Builder()
                .url("http://192.168.1.63:8080/album/login")
                .post(countRequestBody)
                .build();
        execute(request);
    }
    //下载
    public void doDownLoad(View view) {
        //创建request对象
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url("http://192.168.1.63:8080/album//files/album.jpg").build();
        //封装成一个请求的任务
        Call call = okHttpClient.newCall(request);
        //同步的请求 Response response = call.execute();
        //  执行请求(异步的请求)
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.i("请求失败:" + e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                LogUtil.i("请求成功:");
                //总的长度
                long totalLength = response.body().contentLength();
                //下载的进度
                long sum = 0;
                InputStream is = response.body().byteStream();
                int len = 0;
                byte [] buff = new byte[1024];
                File file = new File(Environment.getExternalStorageDirectory(),"album.jpg");
                FileOutputStream os = new FileOutputStream(file);
                while ((len=is.read(buff))!=-1){
                    os.write(buff,0,len);
                    sum+=len;
                    LogUtil.i(sum+"/"+totalLength);
                }
                os.flush();;
                os.close();
                is.close();
                LogUtil.i("success");
            }
        });
    }



    private void execute(Request request) {
        //封装成一个请求的任务
        Call call = okHttpClient.newCall(request);
        //同步的请求 Response response = call.execute();
        //  执行请求(异步的请求)
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.i("请求失败:" + e.toString());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                LogUtil.i("请求成功:" + response.body().string());
            }
        });
    }
}

因为RequestBody没有提供上传的进度,所以在上传的时候包装RequestBody用来计算上传的进度

package com.chs.okhttpdemo;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * 作者:chs on 2017/1/19 16:05
 * 邮箱:657083984@qq.com
 * 包装RequestBody用来计算上传的进度
 */

public class ProgressRequestBody extends RequestBody {
    //真正的mRequestBody
    private RequestBody mRequestBody;
    //上传回调接口
    private OnProgressListener mProgressListener;

    public ProgressRequestBody(RequestBody requestBody, OnProgressListener progressListener) {
        mRequestBody = requestBody;
        mProgressListener = progressListener;
    }

    public interface OnProgressListener {
        void OnProgress(long byteWrite,long contentLength);
    }
    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

    @Override
    public long contentLength() {
        try {
            return mRequestBody.contentLength();
        } catch (IOException e) {
            return -1;
        }
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CountingSink countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(countingSink);
        mRequestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }

    protected final class CountingSink extends ForwardingSink{
        private long byteWrite;
        public CountingSink(Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            byteWrite+=byteCount;
            mProgressListener.OnProgress(byteWrite,contentLength());
        }
    }
}
原文  http://blog.csdn.net/mingyunxiaohai/article/details/54618008
正文到此结束
Loading...