搞定 Android OkHttp3 网络请求

1 开始使用

  • https://github.com/square/okhttp
// okhttp:3.8.0 里面引用了 okio:1.13.0
compile 'com.squareup.okhttp3:okhttp:3.8.0'
//MockWebServer
//testCompile 'com.squareup.okhttp3:mockwebserver:3.8.0'

  • 默认客户端
String url = "https://github.com/";
final OkHttpClient okHttpClient=new OkHttpClient();
  • 设置请求超时
okHttpClient = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build();
  • 设置缓存
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024;
okHttpClient = new OkHttpClient.Builder()
        .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
        .build();

2 GET

  • 同步 GET
   final Request request=new Request.Builder().url(url).build();
        //get
       new Thread(new Runnable() {
           @Override
           public void run() {
               //
               try {
                   Response response=okHttpClient.newCall(request).execute();
                   if (response.isSuccessful()){
                       String body=response.body().string();
                       String headers=response.headers().toString();
                       Log.i("zfq", "run: ");
                   }else {
                       Log.e("zfq", "run: "+response.code()+response.message());
                   }
                   Log.i("zfq", "run: ");
               } catch (IOException e) {
                   e.printStackTrace();
               }

               //
           }
       }).start();

   
  • 异步 GET
     //get
     okHttpClient.newCall(request).enqueue(null);
     //
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("zfq", "onFailure: "+e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String body=response.body().string();
                String headers=response.headers().toString();
                Log.i("zfq", "onResponse: ");
            }
        });

3 POST

  • 异步、同步不再赘述
  • MediaType
    /**
     * "application/x-www-form-urlencoded",是默认的MIME内容编码类型,一般可以用于所有的情况,但是在传输比较大的二进制或者文本数据时效率低。
这时候应该使用"multipart/form-data"。如上传文件或者二进制数据和非ASCII数据。
     */
    public static final MediaType MEDIA_TYPE_NORAML_FORM = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
    
    //既可以提交普通键值对,也可以提交(多个)文件键值对。
    public static final MediaType MEDIA_TYPE_MULTIPART_FORM = MediaType.parse("multipart/form-data;charset=utf-8");
   
    //只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)
    public static final MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream");
    
    public static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain;charset=utf-8");
    
    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=utf-8");

  • POST String

  MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain;charset=utf-8");
        String str = "AndroidContent";
        RequestBody requestBody=RequestBody.create(MEDIA_TYPE_TEXT,str);
        Request requestPost=new Request.Builder().url(url).post(requestBody).build();
        
  • POST Json

  MediaType MEDIA_TYPE_JSON= MediaType.parse("application/json; charset=utf-8");
        String jsonStr = "[\"Android\",\"Java\",\"C#\"]";
        RequestBody requestBody=RequestBody.create(MEDIA_TYPE_JSON,jsonStr);
        Request requestPost=new Request.Builder().url(url).post(requestBody).build();
        
  • POST Params
        String paramsStr="name=zfq&qq=1212";
        MediaType MEDIA_TYPE_NORAML_FORM = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
        RequestBody requestBody=RequestBody.create(MEDIA_TYPE_NORAML_FORM,paramsStr);
        Request requestPost=new Request.Builder().url(url).post(requestBody).build();
        

  • POST File
 MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
       File file = new File("README.md");
       Request request = new Request.Builder()
                    .url("https://api.github.com/markdown/raw")
                    .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
                    .build();
        Response response = okHttpClient.newCall(request).execute();
  • POST Stream
final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
        File file = new File("README.md");
        final FileInputStream fileInputStream1=new FileInputStream(file);
        RequestBody requestBody1=new RequestBody() {
            @Nullable
            @Override
            public MediaType contentType() {
                return MEDIA_TYPE_MARKDOWN;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                OutputStream outputStream=sink.outputStream();
                int length;
                byte[] buffer = new byte[1024];
                while ((length = fileInputStream1.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, length);
                }
            }
        };

        RequestBody requestBody2=new RequestBody() {
            @Nullable
            @Override
            public MediaType contentType() {
                return MEDIA_TYPE_MARKDOWN;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                int length;
                byte[] buffer = new byte[1024];
                while ((length = fileInputStream1.read(buffer)) != -1) {
                    sink.write(buffer, 0, length);
                }
            }
        };

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody1)
                .build();

4 返回类型

Response response=okHttpClient.newCall(requestPost).execute();
//
            String string=response.body().string();//
            byte[] bytes= response.body().bytes();//
            InputStream inputStream=response.body().byteStream();//
            Reader reader=response.body().charStream();//
            
            ……
            
            //文件保存
               FileOutputStream fileOutputStream = new FileOutputStream(new File(
                    "android.jpg"));
            //
            int length;
            byte[] buffer = new byte[1024];
            while ((length = inputStream.read(buffer)) != -1) {
               // System.out.println(length);
                fileOutputStream.write(buffer, 0, length);
            }

5 Headers

  • 设置请求头
  Request request = new Request.Builder()
                .url(url)
                .header("headerKey1", "headerValue1")// 设置请求头
                .headers(Headers headers)// 批量设置请求头
                .addHeader("headerKey2", "headerValue2")// 追加请求头
                .removeHeader("headerKey2")//去除请求头
                .build();
  • 获取请求头
        Response response=okHttpClient.newCall(request).execute();
        response.header("responseHeader");
        response.header("responseHeader", "defaultValue");
        //
        Headers headers = response.headers();
      

6 Form Params

  • 其实FormBody内部就是封装了
MediaType CONTENT_TYPE =MediaType.parse("application/x-www-form-urlencoded");
  • 所以就是相当于【3 POST Params 】
  RequestBody formBody = new FormBody.Builder()
                .add("platform", "android")
                .add("name", "dasd")
                .add("subject", "231321")
                .build();
Request request = new Request.Builder().url(url).post(formBody).build();

7 MultipartBody 上传文件同时传其他字段

  • MultipartBody extends RequestBody
    RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addPart()
                .addFormDataPart("title", "Square Logo")
                .addFormDataPart("image", "logo-square.png",
                        RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
                .build();

        Request request = new Request.Builder()
                .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
                .url("https://api.imgur.com/3/image")
                .post(requestBody)
                .build();

8 配合 Gson

  Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()){
        User user = new Gson().fromJson(response.body().charStream(), User.class);
        }

9 取消请求

  
        call.cancel();//取消请求,不能取消已经准备完成的请求
        
        okHttpClient.dispatcher().cancelAll();//取消所有请求

参考文章

  • OkHttp使用完全教程 http://www.jianshu.com/p/ca8a982a116b
  • Android网络请求库 - Say hello to OkHttp http://blog.csdn.net/ghost_programmer/article/details/52253359
  • Android网络编程(六)OkHttp3用法全解析 http://blog.csdn.net/itachi85/article/details/51190687

你可能感兴趣的:(搞定 Android OkHttp3 网络请求)