转载出处:
http://blog.csdn.net/lmj623565791/article/details/49734867;
本文出自:【张鸿洋的博客】html
以前写了篇Android OkHttp彻底解析 是时候来了解OkHttp了,其实主要是做为okhttp的普及文章,固然里面也简单封装了工具类,没想到关注和使用的人还挺多的,因为这股热情,该工具类中的方法也是剧增,各类重载方法,以至于使用起来极不方便,实在惭愧。android
因而,在这个周末,抽点时间对该工具类,进行了从新的拆解与编写,顺便完善下功能,尽量的提高其使用起来的方便性和易扩展性。git
标题的改善,也是指的是对于我以前的代码进行改善。程序员
若是你对okhttp不了解,能够经过Android OkHttp彻底解析 是时候来了解OkHttp了进行了解。github
ok,那么目前,该封装库志支持:web
源码地址:https://github.com/hongyangAndroid/okhttp-utilsjson
引入:设计模式
Android Studio服务器
使用前,对于Android Studio的用户,能够选择添加:session
compile project(':okhttputils')
或者
compile 'com.zhy:okhttputils:2.0.0'
目前基本的用法格式为:
OkHttpUtils .get() .url(url) .addParams("username", "hyman") .addParams("password", "123") .build() .execute(callback);
经过链式去根据本身的须要添加各类参数,最后调用execute(callback)进行执行,传入callback则表明是异步。若是单纯的execute()则表明同步的方法调用。
能够看到,取消了以前一堆的get重载方法,参数也能够进行灵活的选择了。
下面简单看一下,所有的用法:
String url = "http://www.csdn.net/"; OkHttpUtils .get() .url(url) .addParams("username", "hyman") .addParams("password", "123") .build() .execute(new StringCallback() { @Override public void onError(Request request, Exception e) { } @Override public void onResponse(String response) { } });
OkHttpUtils .post() .url(url) .addParams("username", "hyman") .addParams("password", "123") .build() .execute(callback);
OkHttpUtils .postString() .url(url) .content(new Gson().toJson(new User("zhy", "123"))) .build() .execute(new MyStringCallback());
将string做为请求体传入到服务端,例如json字符串。
OkHttpUtils .postFile() .url(url) .file(file) .build() .execute(new MyStringCallback());
将file做为请求体传入到服务端.
OkHttpUtils.post()// .addFile("mFile", "messenger_01.png", file)// .addFile("mFile", "test1.txt", file2)// .url(url) .params(params)// .headers(headers)// .build()// .execute(new MyStringCallback());
OkHttpUtils// .get()// .url(url)// .build()// .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "gson-2.2.1.jar")// { @Override public void inProgress(float progress) { mProgressBar.setProgress((int) (100 * progress)); } @Override public void onError(Request request, Exception e) { Log.e(TAG, "onError :" + e.getMessage()); } @Override public void onResponse(File file) { Log.e(TAG, "onResponse :" + file.getAbsolutePath()); } });
OkHttpUtils .get()// .url(url)// .build()// .execute(new BitmapCallback() { @Override public void onError(Request request, Exception e) { mTv.setText("onError:" + e.getMessage()); } @Override public void onResponse(Bitmap bitmap) { mImageView.setImageBitmap(bitmap); } });
哈,目前来看,清晰多了。
new Callback<?>() { //... @Override public void inProgress(float progress) { //use progress: 0 ~ 1 } }
对于传入的callback有个inProgress方法,须要拿到进度直接复写该方法便可。
目前去除了Gson的依赖,提供了自定义Callback的方式,让用户本身去解析返回的数据,目前提供了StringCallback
,FileCallback
,BitmapCallback
分别用于返回string,文件下载,加载图片。
固然若是你但愿解析为对象,你能够:
public abstract class UserCallback extends Callback<User> { //非UI线程,支持任何耗时操做 @Override public User parseNetworkResponse(Response response) throws IOException { String string = response.body().string(); User user = new Gson().fromJson(string, User.class); return user; } }
本身使用本身喜欢的Json解析库完成便可。
解析成List<User>
,则以下:
public abstract class ListUserCallback extends Callback<List<User>> { @Override public List<User> parseNetworkResponse(Response response) throws IOException { String string = response.body().string(); List<User> user = new Gson().fromJson(string, List.class); return user; } }
很是简单,拿到xxx.cert的证书。
而后调用
OkHttpUtils.getInstance()
.setCertificates(inputstream);
建议使用方式,例如个人证书放在assets目录:
/** * Created by zhy on 15/8/25. */ public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); try { OkHttpUtils .getInstance() .setCertificates(getAssets().open("aaa.cer"), getAssets().open("server.cer")); } catch (IOException e) { e.printStackTrace(); } } }
便可。别忘了注册Application。
注意:若是https网站为权威机构颁发的证书,不须要以上设置。自签名的证书才须要。
能够在Application中,经过:
OkHttpClient client =
OkHttpUtils.getInstance().getOkHttpClient();
而后调用client的各类set方法。
例如:
client.setConnectTimeout(100000, TimeUnit.MILLISECONDS);
好比涉及到文件的须要设置读写等待时间多一点。
OkHttpUtils .get()// .url(url)// .tag(this)// .build()// .connTimeOut(20000) .readTimeOut(20000) .writeTimeOut(20000) .execute()
调用build()以后,能够随即设置各类timeOut.
RequestCall call = OkHttpUtils.get().url(url).build();
call.cancel()
目前对于支持的方法都添加了最后一个参数Object tag
,取消则经过OkHttpUtils.cancelTag(tag)
执行。
例如:在Activity中,当Activity销毁取消请求:
OkHttpUtils .get()// .url(url)// .tag(this)// .build()// @Override protected void onDestroy() { super.onDestroy(); //能够取消同一个tag的 OkHttpUtils.cancelTag(this);//取消以Activity.this做为tag的请求 }
好比,当前Activity页面全部的请求以Activity对象做为tag,能够在onDestory里面统一取消。
其实整个封装的过程比较简单,这里简单描述下,对于okhttp一个请求的流程大体是这样的:
//建立okHttpClient对象 OkHttpClient mOkHttpClient = new OkHttpClient(); //建立一个Request final Request request = new Request.Builder() .url("https://github.com/hongyangAndroid") .build(); //new call Call call = mOkHttpClient.newCall(request); //请求加入调度 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(); } });
其中主要的差别,其实就是request的构建过程。
我对Request抽象了一个类:OkHttpRequest
public abstract class OkHttpRequest { protected RequestBody requestBody; protected Request request; protected String url; protected String tag; protected Map<String, String> params; protected Map<String, String> headers; protected OkHttpRequest(String url, String tag, Map<String, String> params, Map<String, String> headers) { this.url = url; this.tag = tag; this.params = params; this.headers = headers; } protected abstract Request buildRequest(); protected abstract RequestBody buildRequestBody(); protected void prepareInvoked(ResultCallback callback) { requestBody = buildRequestBody(); requestBody = wrapRequestBody(requestBody, callback); request = buildRequest(); } protected RequestBody wrapRequestBody(RequestBody requestBody, final ResultCallback callback) { return requestBody; } public void invokeAsyn(ResultCallback callback) { prepareInvoked(callback); mOkHttpClientManager.execute(request, callback); } // other common methods }
一个request的构建呢,我分三个步骤:buildRequestBody
, wrapRequestBody
,buildRequest
这样的次序,当以上三个方法没有问题时,咱们就拿到了request,而后执行便可。
可是对于不一样的请求,requestBody以及request的构建过程是不一样的,因此你们能够看到buildRequestBody
,buildRequest
为抽象的方法,也就是不一样的请求类,好比OkHttpGetRequest
、OkHttpPostRequest
等须要本身去构建本身的request。
对于wrapRequestBody
方法呢,能够看到它默认基本属于空实现,主要是由于并不是全部的请求类都须要复写它,只有上传的时候呢,须要回调进度,须要对requestBody进行包装,因此这个方法相似于一个钩子。
其实这个过程有点相似模板方法模式,有兴趣能够看看一个短篇介绍设计模式 模版方法模式 展示程序员的一天 .
对于更加详细的用法,能够查看github上面的readme,以及demo,目前demo包含:
对于上传文件的两个按钮,须要本身搭建服务器,其余的按钮能够直接测试。
最后,因为本人水平有限,以及时间比较仓促~~发现问题,欢迎提issue,我会抽时间解决。 have a nice day ~