最近在学OKHttp,看了一些文章,自己也学着对其做了一点封装。
首先,需要了解OKHttp的网络请求过程:
先初始化OkHttpClient对象,接着设置读取、连接的超时时间等配置。在这里配置如下:
mOkHttpClient = new OkHttpClient(); mOkHttpClient.newBuilder() .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .cookieJar(mOkHttpClient.cookieJar()) .cache(new Cache(cacheDirectory, cacheSize)) .build();cacheDirectory是文件目录,cacheSize是缓存目录的大小
1).对于get方式的请求:
利用请求的url构造request对象
Request request = new Request.Builder().url(url).build();
接下来如果采用异步的get方式请求,就是:
mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { //失败的回调 } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) {
String str = response.body().string();} }}) ; 在这里通过response.body()可以获取字符串、字节数组、流等数据格式。如果返回json格式的字符串,就可以在这里利用各种json的解析库进行解析;流的话就可以进行文件的下载,后面有具体的封装。
如果是采用同步的get方式请求,就是:
mOkHttpClient.newCall(request).execute(); 这里返回Response对象,这个方式会阻塞线程
2).对于post方式的请求:
我们都知道,对于post方式的请求,其请求的参数是放在请求体当中,因此,需要先构造请求体,然后利用请求体来构造Request对象
private Request buildPostRequest(String url, List params) { FormBody.Builder builder = new FormBody.Builder(); for (Param param : params) { builder.add(param.key, param.value); } RequestBody requestBody = builder.build(); return new Request.Builder().url(url).post(requestBody).build(); }
然后接下来的步骤和get就是一样的。post方式也有同步的方法,和get的同步一样
如果是下载文件的话,就需要先通过response.body().byteStream()方式获取字节流,然后将字节流写入sd卡中,具体封装如下:
public File saveFile(final ResultCallback callback, Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = response.body().byteStream(); final long total = response.body().contentLength(); long sum = 0; File dir = new File(destFileDir); if (!dir.exists()) { dir.mkdirs(); } final File file = new File(dir, getPhotoFileName()); fos = new FileOutputStream(file); while ((len = is.read(buf)) != -1) { sum += len; fos.write(buf, 0, len); final long finalSum = sum; mDelivery.post(new Runnable() { @Override public void run() { if (callback != null) { if (finalSum * 1.0f / total != 1.0) { callback.onProgress(finalSum * 1.0f / total, total); } else { callback.onSuccess(file); } } } }); if (finalSum * 1.0f / total == 1.0) { break; } } fos.flush(); return file; } finally { try { if (is != null) is.close(); } catch (IOException e) { } try { if (fos != null) fos.close(); } catch (IOException e) { } } }ResultCallback 类是一个抽象类,封装了请求成功与失败,以及下载文件的进度的方法。mDelivery是主线程的Handler对象,用于更新UI。
以上对关键部分作出了解释,最后还是附上完整的封装的代码吧(只封装了get和post以及文件下载和上传(上传没有测试)的方法,其他的请求方式如:put等请求就没有封装了,如果有需求,可以参见:http://blog.csdn.net/lmj623565791/article/details/49734867)
对于使用OKHttp作为网络请求的框架,想到了可以将Fresco加载图片的框架改成OKHttp作为网络请求框架,因为Fresco如果没有配置的话,默认使用的是HttpURLConnection作为网络请求层,改成OKHttp也很简单,代码如下:
当然,首先需要引入相关的包
dependencies {
// your project's other dependencies
compile "com.facebook.fresco:fresco:0.9.0+"
compile 'com.facebook.fresco:imagepipeline-okhttp:0.9.0+'
}
private void initFresco(){ OkHttpClient mOkHttpClient = new OkHttpClient(); Set注意,现在OKHttpClient对象不是okhttp3下面的,而是com.squareup.okhttp包下面的。listeners = new HashSet<>(); listeners.add(new RequestLoggingListener()); ImagePipelineConfig config = OkHttpImagePipelineConfigFactory .newBuilder(this, mOkHttpClient) .setDownsampleEnabled(true) .setRequestListeners(listeners) .build(); Fresco.initialize(this, config); }
以上是我学习okhttp的一些总结,有些不对的地方希望大神们指教啊。
最后将封装的工具类和例子都上传至我的github,欢迎download