OkHttp的使用详解

来源:互联网 发布:java如何实现线程同步 编辑:程序博客网 时间:2024/05/17 18:42

   一.说明   

      虽说现在网络层框架很多,比如volley,nohttp,okhttp等等,但是目前okhttp还是用的最多的。所以说详细的了解okhttp的使用,

源码解析和okhttp的封装是十分必要的,这一系列文章将从okhttp的使用开始

        OKHttp是Android版Http客户端。非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存。默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题。如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求。另外

从Android4.4开始HttpURLConnection的底层实现采用的是okHttp。


   二.使用       

   1.安装

 

      gradle:

    compile 'com.squareup.okhttp:okhttp:2.4.0'    compile 'com.squareup.okio:okio:1.5.0'
    2.Http Get请求

       

    //创建OkHttp请求对象    OkHttpClient client = new OkHttpClient();     //每一次网络请求都是一个Request,Request.Builder传入url,header,params,method等信息    Request request = new Request.Builder().url(url).build();    //通过request封装一个Call对象,将请求封装成任务,既然是个任务就有execute()和cancel()等方法    Call call=client.newCall(request);    //然后直接execute执行得到Response对象,这个方法是个阻塞的方法,通过Response可以得到code,message等信息。    Response response = call.execute();        if (response.isSuccessful()) {            boolean fromCache = response.cacheResponse() != null;       return response.body().string();    } else {               throw new IOException("Unexpected code " + response);    }
     上面是同步的方式,异步的如下

         

    //请求加入调度    call.enqueue(new Callback()        {            @Override            public void onFailure(Request request, IOException e)            {            }            @Override            public void onResponse(final Response response) throws IOException            {                    //String htmlStr =  response.body().string();                    //InputStream is=response.body().byteStream();            }    });
      onResponse执行的线程是不是ui线程,如果要操作控件,还需要通过handler
      

    3.Post请求
   
上面对OkHttp的Get请求分析完之后,OkHttp的整个请求流程和处理流程就清晰,Post请求和Get请求的流程都是一样,区别只是在于Request对象构造上有区别。
   
(1)Post提交键值对

    

 RequestBody body = new FormEncodingBuilder()    .add("platform", "android")    .add("name", "bug")    .add("subject", "XXXXXXXXXXXXXXX")    .build();         Request request = new Request.Builder()      .url(url)      .post(body)      .build();  client.newCall(request).enqueue(new Callback(){});   

  
(2)Post提交json

    

  public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");  OkHttpClient client = new OkHttpClient();  RequestBody body = RequestBody.create(JSON, json);  Request request = new Request.Builder()    .url(url)    .post(body)    .build();  client.newCall(request).enqueue(new Callback(){})

 
(3)基于http的文件上传

  

File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");   RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);   RequestBody requestBody = new MultipartBuilder()     .type(MultipartBuilder.FORM)     .addPart(Headers.of(         "Content-Disposition",          "form-data; name=\"mFile\";          filename=\"wjd.mp4\""), fileBody)     .build();      Request request = new Request.Builder()    .url("http://192.168.1.103:8080/okHttpServer/fileUpload")    .post(requestBody);    .build();        Call call = mOkHttpClient.newCall(request);    call.enqueue(new Callback()    {      //...   });

    通过MultipartBuilder的addPart方法可以添加键值对或者文件。  

  4.编码问题

   在OkHttp中,无论是Get请求还是Post请求所有参数的编码方式都是默认采用UTF-8的编码方式进行编码。

   所以在进行Get请求或Post请求时,文本参数都不需要我们进行手动编码,但是在服务端进行参数解析时,需要做简单的处理,这里我只说明tomcat下运行的Java后台服务的处理方式:

 1.针对Get请求,我们只需要在tomcat的server.xml文件中设置默认编码方式(URIEncoding="UTF-8" )为UTF-8即可,注意此编码设置只对Get请求有效。

  2.针对Post请求,我们在解析获取参数值之前需要手动设置请求的编码方式为UTF-8,如:req.setCharacterEncoding("UTF-8");

 
5.取消一个call

    
使用Call.cancel()可以立即停止掉一个正在执行的call。如果一个线程正在写请求或者读响应,将会引发IOException。
 当call没有必要的时候,使用这个api可以节约网络资源。例如当用户离开一个应用时。不管同步还是异步的call都可以取消。
 
   使用Request.Builder.tag(tag)来分配一个标签。之后你就可以用OkHttpClient.cancel(tag)来取消所有带有这个tag的call

  


6.设置连接和读写时间,cookie的持久化保存,https的支持,

   

       <span style="font-family:SimSun;"> //cookie信息的持久化保存        CookieHandler cookieHandler = new CookieManager(new PersistentCookieStore(context),                CookiePolicy.ACCEPT_ALL);        //Interceptor是拦截器, 在发送之前, 添加一些参数, 或者获取一些信息.loggingInterceptor是打印参数        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();        logging.setLevel(HttpLoggingInterceptor.Level.BODY);                //设置缓存的文件                File httpCacheDirectory = new File(context.getExternalCacheDir(), "xxx");        //设置可访问所有的https网站,可以把第一个参数改成具体网站证书的inputstream,比如getAssets().open("xx");        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);                OkHttpClient okHttpClient = new OkHttpClient.Builder()                //设置网络超时                .readTimeout(7676, TimeUnit.MILLISECONDS)                .connectTimeout(7676,TimeUnit.MILLISECONDS)                //设置拦截器来打印网络请求的返回结果                .addInterceptor(logging)                .cookieJar(new JavaNetCookieJar(cookieHandler))                //开启okHttp缓存                .setCache(new Cache(httpCacheDirectory,10 * 1024 * 1024));                //对https网站的支持                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager))                //通过设置拦截器的方式来addHeader                .addInterceptor(new Interceptor() {                           @Override           public Response intercept(Chain chain) throws IOException {              Request request = chain.request()               .newBuilder()               .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")               .addHeader("Accept-Encoding", "gzip, deflate")               .addHeader("Connection", "keep-alive")               .addHeader("Accept", "*/*")               .addHeader("Cookie", "add cookies here")               .build();               return chain.proceed(request);              }            }))            .build();</span>                     
     

     okhttp的使用差不多也就这么多,okhttp的官方不建议创建多个OkHttpClient对象 ,我们在项目中使用肯定要自己做封装,或者使用别人的封装框架。在后面我也会试着去自己封装一个全能的OkHttpUtils框架,这需要时间


           

  


       

1 0