您的位置:首页 > 理论基础 > 计算机网络

OkHttp的使用详解

2016-08-20 15:08 351 查看
   一.说明   

      虽说现在网络层框架很多,比如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的使用差不多也就这么多,[b]okhttp的官方不建议创建多个OkHttpClient对象 ,[b][b]我们在项目中使用肯定要自己做封装,或者使用别人的封装框架。在后面我也会试着去自己封装一个全能的OkHttpUtils框架,这需要时间[/b][/b][/b]



           


  

       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  OkHttp详解 Okhttp